It extended the Lilywhites' unbeaten sequence against the Ashton Gate outfit to a remarkable 15 matches, stretching back to 2011.
Johnson netted from the spot in the 21st minute after Scott Sinclair had gone down in the box under a challenge from Tyler Moore.
Referee Geoff Eltringham initially played advantage but when Tom Barkhuizen's shot came back off the bar, the official brought back play and pointed to the spot.
North End deservedly led at the break but in the second half they had to fight a strong rear guard action to hold the Robins at bay.
Declan Rudd pulled off a couple of good saves, with Paul Huntington and Ben Davies strong in front of him - Huntington winning so much in the air.
There were a couple of chances on the counter attack late on for PNE to score again, substitutes Tom Bayliss and Emil Riis having sights on goal.
One goal proved sufficient though, sending them into Christmas in good heart.
The PNE side had shown two changes to the one beaten at Barnsley last Tuesday night, with Sinclair and Huntington returning to the starting XI.
Emil Riis dropped to the bench, while injury ruled out Andrew Hughes.
After using a 3-5-2 at Barnsley, Alex Neil reverted to his tried and tested 4-2-3-1, Sean Maguire leading the attack with Johnson in the supporting role behind him.
The opening quarter of an hour was low key before North End began to find some tempo to their play.
A run from Sinclair carried him to the edge of the box, his shot clipping off a defender and going behind for a corner.
Maguire saw a shot on the half-turn run through to the keeper before the Lilywhites took a 21st minute lead.
A fine pass from Paul Gallagher opened-up the Robins defence and was collected by Sinclair just inside the box.
He went to ground under Moore's challenge, the ball running loose to Barkhuizen whose shot came back off the bar.
Having initially played the advantage, Mr Eltringham brought play back and pointed to the penalty spot for the challenge on Sinclair.
Johnson dispatched the penalty into the bottom right corner, sending keeper Daniel Bentley the wrong way.
Maguire took advantage of hesitancy in the visitors' midfield ranks to steal the ball and drive down the left channel but having got into the box, he was tackled when caught in two minds if to shoot or square it.
City's best chance of the first half was Tomas Kalas' shot the back post after Callum O'Dowda's free-kick had been flicked on, Huntington getting in a good block to take the ball behind at the expense of a corner.
Two chances fell PNE's way in first-half stoppage-time, the first coming from Josh Earl rolling a pass to Maguire on the edge of the box, the striker's shot on the turn deflected into the keeper's gloves.
Then with virtually the last kick of the half, Sinclair cushioned a volley too close to keeper Bentley after Barkhuizen had sped along the right-wing and delivered a fine cross on the run into the middle.
The visitors made a double substitution at the break and changed shape, that resulting in them starting the second half much the better of the two sides.
One of those substitutes, Antoine Semenyo, forced a save out of Rudd at the far post after meeting a cross from the right.
Rudd was to produce a fine save in the 56th minute, the North End keeper diving to his right to get a glove to O'Dowda's 20-yard shot after the Robins had worked the ball in field from the left wing.
To try and get North End back on the front foot, Neil made a double change in the 69th minute, Riis replacing Maguire and Joe Rafferty taking over from Darnell Fisher at right-back.
Fisher had been booked for a foul on Semenyo and then a challenge on Tyreeq Bakinson brought a warning from Mr Eltringham.
Hence Neil leaned on the side of caution and made that change.
North End increasingly had to rely on the counter-attack to go forward as the Robins continued to pin them back.
Once such break almost brought them some joy in the 85th minute, Riis leading the charge from his own half and showing some fine footwork.
The Dane's pass played in fellow sub Bayliss who lifted a shot over the bar.
Play swung back to the other end, with Rudd needing to produce a fine save to keep the lead intact.
He sprung back to tip O'Dowda's header over the bar after the midfielder had got behind the PNE defence.
Just into stoppage-time another Preston counter almost led to a second goal and a more comfortable finale.
Sinclair led it, his pass playing in Riis down the left side of the box, the Dane's low shot looking destined for the far corner until Bentley got enough of a touch on it to take it past the post.
PNE: Rudd, Fisher (Rafferty 69), Huntington, Davies, Earl, Browne, Gallagher (Bayliss 76), Barkhuizen, Johnson (Stockley 79), Sinclair, Maguire (Riis 69). Subs (not used): Harrop, Storey, Holland-Wilkinson, O'Reilly, Ripley.
Bristol City: Bentley, Vyner, Kalas, Moore (Semenyo 46), Hunt, O'Dowda, Nagy, Massengo (Bakinson 46), Rowe, Martin, Wells. Subs (not used): Mariappa, Smith, Edwards, Pearson, Bell, Towler, O'Leary.
Referee: Geoff Eltringham (County Durham)
Thanks for reading. If you value what we do and are able to support us, a digital subscription is just £1 per month for the first two months. Try us today by clicking here