In a rain-curtailed match, the Proteas fell three runs short of the revised Duckworth-Lewis (D/L) target of 190 to get in 21 overs.
With the narrow win, the hosts now trail 1-3 in the series after losing the first three matches.
All-rounder Dasun Shanaka was the star of the show for Sri Lanka with a rapid half-century with the bat along with the vital wicket of Reeza Hendricks with the ball.
Batting first at Kandy, the Lankans put up 306-7 in 39 overs with Shanaka top-scoring with a 34-ball 65. The all-rounder’s innings contained four boundaries and five sixes.
Despite a half-century from Kusal Perera, the Sri Lankans had been reduced to 195-7 before Thisara Perera and Shanaka turned their fortunes around with some stupendous hitting at the death.
Perera remained unbeaten on 51 as the hosts breached the 300-run mark at the end.
In reply, South Africa appeared to be on track for victory with Hashim Amla and JP Duminy guiding the side to 108-2 in just nine overs before Sri Lanka hit back with a flurry of wickets.
Despite a middle-order collapse, the visitors were within sight of a win with 16 runs required off the final two overs with three wickets in hand.
Thisara Perera then bowled a terrific penultimate over which fetched only eight runs along with a wicket. With eight runs required off the final over, Suranga Lakmal delivered the vital blow with the second ball by removing David Miller. That proved to be the end of the Proteas’ hopes with Junior Dala managing only three runs off the final two deliveries.
The fifth and final ODI between the two teams will be held at Colombo on August 12.
Sri Lanka: 306-7 (39 overs)
Dasun Shanaka – 65 (34)
Kusal Perera – 51 (32)
Thisara Perera – 51 not out (45)
South Africa: 187-9 (21 overs)
Hashim Amla – 40 (23)
Suranga Lakmal : 3-46
Know more about Sport360 Application