The Springboks managed three tries, with Coenie Oosthuizen and Cobus Reinach also scoring, but showed none of the accuracy that helped them beat England at Twickenham last weekend, against an Italian side full of guts and passion.
Their other points came from a Pat Lambie penalty and two conversions from Handre Pollard.
Italy contested and forced the visitors into errors, with their points coming from two penalties by flyhalf Kelly Haimona.
Italian captain Sergio Parisse said the performance showed the potential of his side.
“I can ask nothing more from my team after what they did out there today. We received lots of criticism and we have fought back well,” he told reporters.
South Africa had averaged over 50 points in their 11 previous meetings with Italy, but found a much more organised defence this time around.
Their captain Jean de Villiers said that, if nothing else, his side had showed their ability to grind out a win.
“This team doesn’t lack commitment. It might not be pretty but we will win. We felt we were probably more than 16 points better than them,” De Villiers said.
“The bench made a difference and this team is shaping up nicely. We’re working towards what we want to achieve.”
New Zealand-born Haimona put Italy in front with an early penalty which was cancelled out by Lambie.
Midway through the first half, South Africa scored their first try as prop Oosthuizen, selected in part for his ability in the loose, barged over from five metres.
Despite being under pressure, the home side scored next as Haimona slotted home another penalty on the stroke of halftime, leaving the Springboks 8-6 ahead at the interval.
It took 20 minutes of the second half, and the introduction of fullback Willie le Roux, for South Africa to score next.
Le Roux broke the line and fed debutant loose forward Nizaam Carr, whose first touch of the ball in international rugby put Reinach clear to score.
Replacement flyhalf Pollard slotted home the conversion, and in the final minute it was his break that set Habana away for the third score — and his 57th try — for the Springboks.
(Reporting by Nick Said in Cape Town; Editing by Ian Chadband)