England closed the gap with a penalty try in the 62nd minute followed by a match winning try from Kyle Sinckler.
As they did during Monday's historic win over South Africa Ireland offered a huge work-rate in defence, typified by their athletic back row.
Working their way into scoring range, Hanrahan slid a 29-metre penalty wide after England's David Sisi was pinged for not rolling away.
With two England players in the bin Barry Daly did brilliantly for Ireland when running a kick back, slipping out of an initial tackle and darting up the right wing.
With England now back on their try-line, the Irish recycled quickly from a couple of rucks and the in-form Hanrahan outfoxed the first defender and showed great strength to scramble over to the left of the posts, 14 minutes in.
The Kerry youngster converted and as Ireland continued to press, retaining possession impressively, a dangerous tackle on Tadhg Beirne saw Addison sin-binned.
A sparkling break from scrum half Marmion, right through the middle of the English defence, laid the platform for the second Irish try in the 26th minute.
A match-ending injury for talismanic flanker Conor Gilsenan temporarily halted Ireland's momentum, but good harrying from Marmion at a scrum forced a turnover.
The mistakes continued from an off-colour England, their kicking skills not a match for the precise punting of Hanrahan and full-back Peter Nelson.
Another positive for Ruddock's charges was the solid nature of the scrum, and they narrowly missed out on a third try when the dangerous Daly was denied by a foot in touch.
That opportunity presented itself after a strong hand-off and surging run from flanker Jordan Coghlan, who sat a Maths Leaving Cert paper earlier in the day.
But Ireland kept hold of the territory and a last-minute ruck offence from Dominic Barrow allowed Hanrahan kick Ireland 15-3 ahead for half-time.
England made a strong start to the second half though, an early penalty from Heathcote helping to get them back on track.
Iain Henderson, Tadhg Beirne and replacement Munster's Shane Buckley did well to disrupt England's rhythm and a bout of heads-up rugby gave the Irish a chance to hit back.
However, Hanrahan could not convert a difficult 37-metre penalty from the right. England unloaded their bench as the final quarter loomed, and that strength in depth eventually proved crucial.
Their reserve scrum half Dan Robson went close to scoring his side's first try after tapping a penalty. Ireland survived on that occasion, but from the resulting scrum the powerful English pack drove forward to earn a penalty try.
The pressure was now really on Ireland and as their error count increased, England took advantage - their bulky forwards helping to maul Sinckler over in the left corner.
Heathcote underlined England's improvement by clipping over a fine conversion for a 20-15 turnaround and they were able to wind down the clock, keeping a frustrated Ireland off the ball and in their own half.
The five-point loss, coupled with South Africa's 52-3 victory over Italy, leaves Ireland third in the table ahead of their final Pool B game against the winless Italians on Tuesday afternoon.
Referee: Lourens van der Merwe (South Africa)
IRELAND U-20: Peter Nelson (Dungannon/Ulster); Barry Daly (UCD/Leinster), Foster Horan (Lansdowne/Leinster), Chris Farrell (Dungannon/Ulster), Sam Coghlan Murray (UCD/Leinster); JJ Hanrahan (UL Bohemians/Munster), Kieran Marmion (Corinthians/Connacht); Des Merrey (Clontarf/Leinster), Niall Scannell (Dolphin/Munster) (capt), Tadhg Furlong (Clontarf/Leinster), Tadhg Beirne (Lansdowne/Leinster), Iain Henderson (Queen's University/Ulster), Jordan Coghlan (UCD/Leinster), Conor Gilsenan (UCD/Mullingar/Leinster), Jack Conan (Old Belvedere/Leinster).
Replacements: Shane Buckley (Garryowen/Munster) for Gilsenan (29 mins), James Rael (Garryowen/Munster) for Scannell (63), Luke McGrath (UCD/Leinster) for Marmion, Jack Carty (Buccaneers/Connacht) for Coghlan Murray (both 68), Alan O'Connor (UCD/Leinster) for Buckley (73), Stuart Olding (Belfast Harlequins/Ulster) for Nelson (77). Not used: Peter Reilly (Lansdowne/Leinster), Jake Cawley (Old Belvedere/Leinster).
ENGLAND U-20: Tommy Bell (London Wasps); Marland Yarde (London Irish), Will Addison (Sale Sharks), Ryan Mills (Gloucester) (capt), Charlie Walker (Harlequins); Tom Heathcote (Bath), Ben Spencer (Saracens); Alec Hepburn (London Wasps), Koree Britton (Gloucester), Kyle Sinckler (Harlequins), Dominic Barrow (Leeds Carnegie), George Merrick (Harlequins), David Sisi (London Irish), Ben Nutley (Northampton Saints), Jack Clifford (Harlequins).
Replacements: Sam Hill (Exeter Chiefs) for Mills (half-time), Dan Robson (Gloucester) for Spencer, Chris Walker (Leeds Carnegie) for Clifford, Ben Ransom (Saracens) for Addison (all 49 mins), Max Crumpton (Saracens) for Britton, Luke Cowan-Dickie (Exeter Chiefs) for Hepburn (both 53), Sam Twomey (Harlequins) for Merrick (60). Not used: Ross Harrison (Sale Sharks).