Kohli struck 112 off 119 balls with the help of 10 boundaries and put on 189 runs for the third wicket with Ajinkya Rahane (79 runs of 86 balls) as India chased down the target of 270 with 4.3 overs to spare.
It was the highest stand for India in South Africa, while Kohli notched up his 20th hundred in a run-chase, out of which 18 have been successfully converted to victories.
Also, this was India's first ODI win against South Africa at Durban, and only their sixth overall in bilateral engagements here since 1992-93.
India got off to a quick start with Rohit Sharma (20) and Shikhar Dhawan (35) adding 33 for the opening wicket. Rohit was looking to play his strokes but miscued one off Morne Morkel (1/35) in the seventh over and was out caught.
More From This Section
Dhawan and Kohli then added 34 runs for the second wicket and the duo were looking good to take advantage of South Africa's spinners, when the former was run-out.
Kohli and Rahane came together thereafter and did not give the Proteas a sniff. Imran Tahir (0/51) was duly taken for runs, while JP Duminy (0/16) and Markram (0/20) had no impact in their short spells.
The most vital aspect of this partnership was the running between wickets. The duo looked to cut down on errors, calling loud and clear. They brought their 100-stand off 112 balls.
Rahane brought up his half-century off 60 balls as their partnership crossed 150 off only 154 balls. India reached 200 in the 36th over.
Rahane was out caught in the 43rd over, while Kohli's innings ended three overs later. He walked off to a rousing reception from the Durban faithful even as the home side were subjected to a demoralizing defeat.
This was after India's leg-spin twins Kuldeep Yadav and Yuzvendra Chahal shared 5 wickets between them as South Africa were restricted to 269/8.
Proteas' skipper Faf du Plessis (120 runs, 112 balls, 11 fours, 2 sixes) scored his ninth ODI hundred after South Africa's top-order collapse. The hosts lost 4 wickets for 51 runs before du Plessis and Chris Morris (37) rescued them with 74-run partnership for the sixth wicket.
Hashim Amla (16) and Quinton de Kock (34) got off to a watchful start. The latter, in particular, took his time for he had been enduring a poor run of form. At the other end, Amla looked in good nick and was scoring at a strike-rate of 90-plus.
Just before this, India had a major injury scare when Virat Kohli hurt his knee while fielding in the seventh over. He struggled with his right leg for a while thereafter, and even went off to the Indian dugout to get attention from the physiotherapist.
South Africa scored 49/1 in the first 10 overs even as Hardik Pandya (0/41) came on to bowl first-change. More importantly though, Kohli went off the field -- this time to the dressing room to get further treatment -- in this interim as the knee niggle continued to bother him.
Chahal trapped de Kock lbw in the 15th over, and the batsman walked without bothering for a review. Had he opted for the referral, he would have survived. Du Plessis, alternately, would have been given out lbw on 18 if India had opted for DRS at the end of the 13th over.
Then Yadav got into the act. He bowled JP Duminy (12) with one that kept low, whilst foxing David Miller (7) into a false shot as Kohli completed a smart forward-diving catch at short extra-cover.
Du Plessis reached his half-century off 54 balls and brought up his 50-partnership with Morris off 57 balls. South Africa recovered to reach 200/5 at the end of 40 overs.
Yadav returned for a final spell to bowl Morris in the 41st over. Du Plessis though stood tall and added 56 runs for the seventh wicket with Andile Phehlukwayo (26 not out). In doing so, he brought up his century off 101 balls.