The winner came just eight minutes into the second half when Johnson cut inside from the right past David Silva and unleashed a left-footed shot which squirmed under Joe Hart and into the bottom corner.
However, the winner was not without controversy with the visitors adamant they should have been awarded a free-kick for a foul on Pablo Zabaleta by Craig Gardner during the build-up.
Sunderland turned in one of their best displays of the season on a day when City played only in patches, and Hart had to turn away Steven Fletcher’s skidding effort and keep out Stephane Sessegnon 10 minutes from time.
However, if Johnson was the hero in front of a delighted Boxing Day crowd of 42,190, keeper Simon Mignolet deserved equal praise.
The Belgian denied Yaya Toure and Silva before the break and Sergio Aguero after it to claim a precious clean sheet and make a huge contribution towards the win.
City arrived determined not to complete an unwanted hat-trick of 1-0 league defeats on Wearside but they could not as they slipped seven points adrift of league leaders Manchester United.
They might have been ahead with just eight minutes gone, but Vincent Kompany’s header came back off the crossbar and Yaya Toure’s goalbound follow-up was hacked away by Mignolet.
City boss Roberto Mancini and Zabaleta were then left appealing in vain for a free-kick for Gardner’s challenge on the full-back, as Johnson picked up possession and cut inside before firing home.
Sessegnon might have doubled his side’s advantage within two minutes, but pulled his effort across the face of goal with City in disarray.
The visitors were almost breached once again on the hour when James McClean picked out Sessegnon in front of goal, but the Benin international could not take the ball in his stride.
Kompany, who had already been booked, was fortunate to escape a second yellow card for a block on McClean as City struggled to contain a Black Cats side growing in confidence by the minute.
Belgium international Mignolet excelled himself once again two minutes later to deny Aguero one on one, but it was Hart in the firing line with 10 minutes remaining when Sessegnon was played in by substitute Fraizer Campbell with the keeper coming out on top.
City battered away at their hosts as time ran down, but with Sunderland defending deep and with tenacity, they simply could not find a way through and McClean almost served up the perfect finish with an 88th-minute shot which flew just wide.