Rohit (49) and Ishan Kishan (42) laid the foundations for the total in an 80-run opening stand before Axar Patel sent the two back in the pavilion with his left-arm spin.
Returning batsman Suryakumar Yadav, who missed the first three losses injured, survived a toe-crushing yorker by Nortje on his first ball but then miscued the next delivery to mid-on for a two-ball duck.
Mumbai lost another wicket before Pandya and David put on 60 to steady the innings ahead of Shepherd's explosive knock.
- Thakur effect -
In reply, Prithvi Shaw hit 66 after losing opening partner David Warner for 10 off Shepherd's seam bowling.
Shaw and the left-handed Abhishek Porel, who hit 41, put on 88 for the second wicket before Jasprit Bumrah removed both.
South Africa's Stubbs raised a fifty in 19 balls but the asking rate kept climbing and Gerald Coetzee took three wickets in the final over to return figures of 4-34.
In the day's second match in Lucknow, Marcus Stoinis hit 58 to guide Lucknow to a total, which looked below par but the bowlers made sure it was enough.
Leg-spinner Ravi Bishnoi took a stunning return catch off his own leg-spin to send Gujarat's impact substitute Kane Williamson out for one.
Left-arm spinner Krunal Pandya, elder brother of Mumbai's Hardik, struck three times, including twice in one over when he took the wicket of Sai Sudarshan for 31 to derail the opposition chase.
Thakur, who bowled skipper Shubman Gill for 19 as his first wicket, then sent down a double-wicket maiden to flatten the batting.
He took two more wicket in the 19th over for his first-ever five wicket haul -- 5-30 -- in T20 cricket.
New pace sensation Mayank Yadav picked up an injury after he bowled just one over for 13 runs.