South Africa were heading for a comfortable win, with four runs needed and five wickets in hand to reach a target of 210 when Malinga yorked Shaun Pollock with the fifth ball of his eighth over.
Andrew Hall then scooped a catch to cover off the next ball.
Jacques Kallis took a single off the next over from Chaminda Vaas but was then caught behind for 86 off the first ball of Malinga's ninth over.
Makhaya Ntini then had his stumps scattered by a fast yorker as Malinga became the first bowler in one-day international history to take four wickets off successive balls.
Charl Langeveldt, who earlier took a career-best five for 39 as Sri Lanka limped to 209 all out, scrambled a single off Malinga before Robin Peterson edged a boundary to clinch a crucial win for South Africa.
The win relieved some of the pressure on South Africa, whose 83-run defeat against Australia in St Kitts Saturday meant they entered the Super Eight phase without any points.
It also ensured that South Africa would collect a 150,000-dollar bonus as the world's number one-ranked team as they cannot be topped by the April 1 cut-off for the International Cricket Councils championship ratings.
Off-spinner Muttiah Muralitharan had appeared the only major obstacle to South Africa's win.
He ended a 95-run stand between captain Graeme Smith (59) and Kallis when he had Smith stumped by Kumar Sangakkara for 59 in his second over.
Muralitharan struck twice off successive balls in the second over of a second spell, and his eighth of the innings, when he took a return catch from Herschelle Gibbs and trapped Mark Boucher leg before.
The whole of the Sri Lankan team, and many in a small crowd, went up when the hat-trick ball to Justin Kemp was caught by Russel Arnold at short leg.
But umpire Daryl Harper gave Kemp not out and replays showed the ball went off Kemps pad. Muralitharan took three for 38.
Earlier Arnold (50) and Tillekeratne Dilshan (58) were mainly responsible for Sri Lanka making a respectable total. They put on 97 for the sixth wicket after their side slumped to 98 for five.
But after Dilshan was caught at third man off Makhaya Ntini, who took two for 26, Sri Lanka lost their last four wickets for one run, with Langeveldt taking three wickets in his final over all to attempted big hits.
Former prison warner Langeveldt, 32, took two wickets in a first spell of two for 22 in six overs.
He came on at a crucial time, replacing opening bowler Shaun Pollock, who was hit for 32 in his first four overs.
Following the example of Australia, who appeared to target Pollock, Sri Lankan opening batsman Upul Tharanga and Sanath Jayasuriya went for their shots against the South African veteran, who holds a big lead at the top of the ICC one-day bowling rankings.
Sri Lankan hopes were raised when left-arm opening bowler Chaminda Vaas bowled AB de Villiers for nought in the first over but Smith batted aggressively with solid support from Kallis as South Africa took control.
Smith hit seven fours and a six in his 65-ball innings before he was drawn down the pitch by a flighted ball from Muralitharan for Sangakkara to make a smart stumping.
Kallis was more sedate, pushing the ball into gaps and taking plenty of ones and twos and seemed on course to steer South Africa home before Malinga struck.