tourists now 27 runs in front.
South Africa, 1-0 up in the three-match series, only have to avoid defeat at Lord's to replace England as the world's top-ranked Test side.
Both teams had collapsed to 54 for four in their first innings but Petersen, who hit two fours off James Anderson before elegantly driving Stuart Broad to the cover boundary, and left-hander Smith held firm.
Earlier on Saturday, Jonathan Bairstow fell just short of a maiden Test hundred as England took a slender first innings lead of six runs, making 315 in reply to South Africa's 309. But the recalled Bairstow had the consolation of posting a Test-best 95 after coming in when England had slumped to 54 for four.
There was extra pressure on the 22-year-old Bairstow's shoulders as he'd been brought in to replace Kevin Pietersen, dropped despite scoring 149 in the drawn second Test at Headingley.
England axed South Africa-born Pietersen for sending "provocative" texts, believed to include criticisms of captain Andrew Strauss, to Proteas players.
Bairstow only made his Test debut in May, at Lord's, but was dropped after his first three matches at this level, all against the West Indies, yielded a mere 38 runs in total.
But the Yorkshireman resumed Saturday on 72 not out, with England then 208 for five.
Vernon Philander struck with the very first delivery with the new ball as Matt Prior, on 27, loosely drove at an outswinger and edged to second slip Jacques Kallis.
Bairstow, the son of late former England wicket-keeper David Bairstow, guided fast bowler Dale Steyn square through the offside for four and clipped Philander through midwicket to go to 90.
But he spent 15 runless balls, all against Morne Morkel, on 95, as the fast bowler tied him down on a sunny day when the blue skies above Lord's offered little assistance to the bowlers.
South Africa 309 & 145-3 (H Amla 57 batting, J Kallis 31, Finn 1-28)
England 315 (J Bairstow 95, I Bell 58, Swann 37, Morkel 4-80, Steyn 40-94)