Tahir finished with four for 27 in 8.3 overs after former captain Hashim Amla scored his 25th ODI century to set Sri Lanka a target of 300 runs.
Sri Lanka were cruising along at 116 for two when Tahir was introduced to the attack in the 18th over and South Africa immediately got a firm grip on the game.
Dinesh Chandimal took on one of South Africa’s best fielders — A.B. de Villiers — on a misfield and was run out by a direct hit.
Three deliveries later, Chamara Kapugedera was foxed by a Tahir googly and was out leg before wicket without scoring.
Upul Tharanga — captain for the day after Angelo Mathews failed a late fitness test on a calf muscle injury — too fell for the googly when he hit one straight to the deep cover fielder.
He top scored with 57 runs.
Sri Lanka never recovered after that and were shot out for 203 runs with still 8.3 overs remaining.
There could be more trouble for the Sri Lankans after they took four hours and seven minutes to finish their overs during the South African innings.
ICC rules stipulate that teams should finish their 50 overs within three-and-a-half hours.
Sri Lankan players face heavy fines and a possible suspension for Tharanga for the next two games of the tournament.
Opener Niroshan Dickwella had given them a blistering start smashing 41 off 33 balls.
The openers added 69 runs in 50 deliveries and they were 87 for one at the end of ten overs whereas South Africa were 32 for none at the same stage.
The middle order failed to capitalize after a good start and they have to win their remaining two games against India and Pakistan to have any hopes of a semi-final berth.
Sri Lanka were excellent against South Africa’s seamers, but the introduction of Tahir derailed their innings.
After being put into bat in overcast conditions, Amla consolidated for South Africa with his 25th ODI hundred and the fifth against Sri Lanka.
He added 145 runs with Francois du Plessis, who contributed with 75 runs off 70 deliveries with six fours.
Amla was run out by a direct hit from Tharanga for a fine 103 that came off 115 deliveries with five fours and two sixes.
J.P. Duminy gave some impetus to the South African innings smashing 38 off 20 deliveries with five fours and a six. Duminy added 45 runs for the sixth wicket with Chris Morris (20).