England, who came into this match on the back of successive defeats by Sri Lanka and Australia, will be assured of a place in the last four if they beat New Zealand in their last group match on Wednesday.
India can reach the knockout phase by beating Bangladesh when they return to Edgbaston on Tuesday.
England's bid to win a first World Cup title is based on aggressive top-order batting but the runs had dried up lately.
That made their 337-7 after captain Eoin Morgan won the toss on a good pitch in Birmingham all the more heartening.
Bairstow top-scored with 111 and all-rounder Ben Stokes added a brisk 79, with India paceman Mohammed Shami taking a career-best 5-69.
"We played extremely well. Jason Roy and Bairstow at the top were magnificent to watch," Morgan said.
"The continuation of partnerships throughout took us to a formidable total.
"From 10-20 overs we got 90-odd runs and that was the winning of the game.
"We took on the spinners and that's the way we want to play our cricket. Hopefully this kick starts it for us."
No side have made more batting second to win a World Cup match than Ireland's 329-7 against England at Bangalore in 2011.
Title contenders India weren't up to the task as their chase petered out on 306-5.
India captain Virat Kohli defended his side's limp chase, saying: "Every team has lost a game or two here and there. No-one likes to lose but we have to take in our stride.
"We are still playing good cricket. The mood is the same in the changing room. We will learn from it and move forward."
India were a long way off from the moment opener KL Rahul was caught and bowled for a duck by Warwickshire paceman Woakes, who reeled off an impressive three straight maidens with the new ball on his home ground.
Rohit Sharma, Rahul's opening partner, should have fallen for four but Joe Root dropped a routine second-slip catch off fast bowler Jofra Archer.
It threatened to be a costly miss with Sharma going on to 102, his third century of the tournament, in front of an overwhelmingly India-supporting capacity crowd of more than 24,000.
Sharma also shared a second-wicket stand of 138 with Kohli, whose 66 was the star batsman's fifth successive fifty of this World Cup.
But Kohli fell when he sliced Liam Plunkett to backward point.