De Villiers’ struck 51 off 58 balls on a turning pitch as the tourists added a swift 143 runs in the afternoon session for the loss of four wickets.
JP Duminy was at the wicket unbeaten on eight at the declaration having lost Quinton de Kock in the last over before the break for 36.
De Kock, beaten by the flight, hit back a return catch to off-spinner Dilruwan Perera.
Perera also accounted for the wickets of Hashim Amla for 22 and De Villiers to finish the innings with figures of four for 79.
Amla hit a catch to short mid-on when he flicked Perera off his legs and De Villiers played the ball onto his stumps as he attempted to pull a delivery.
Left-arm spinner Rangana Herath picked up the other wicket to fall in the session, bowling Faf du Plessis for 37 with a delivery that pitched outside leg stump and flicked his off bail.
Herath also grabbed the wicket of first innings century-maker Dean Elgar for 12 in the morning session when the opening batsman nicked one to Dinesh Chandimal as he attempted a drive.
Alviro Petersen was next to go for 32 shortly before lunch when he hit a thin edge to Chandimal off Perera’s bowling. The South African batsman was unsuccessful in his challenge of the call.
Earlier in the morning, the tourists made quick work of Sri Lanka’s final pair with Herath’s 132 minute resistance finally ended by Morne Morkel, who got him to edge a catch to De Villiers at second slip for 19.
Shaminda Eranga, batting with some pain after needing eight stitches in his right hand, was left unbeaten on one.
Steyn finished with figures of five for 54 and Morkel had three for 49 as the hosts were limited to 292 all out. (Reuters)