Jamie Shaul went over to put Hull ahead, but Saints led at half-time thanks to James Roby's try from dummy-half and a penalty from Percival.
Percival went over after good work from Theo Fages, before Mahe Fonua crossed to reduce the visitors' deficit.
But Percival touched down acrobatically from Fages' kick, before Danny Richardson's drop-kick sealed the win.
Saints are now almost certain to finish in Super League's top eight, with only Catalans - six points behind with three games to play - able to catch them.
Hull, who lost 45-0 when the two sides met in May, were already assured of a top-eight finish, as they stay fourth in the table.
The result could have been different had Fetuli Talanoa not had a try correctly disallowed for a push on Tommy Makinson shortly before Percival's second try, but instead Saints held on for a sixth consecutive home victory.
St Helens: Lomax; Makinson, Morgan, Percival, Grace; Fages, Richardson; Douglas, Roby, Thompson, Taia, Peyroux, Knowles.
Replacements: Walmsley, Amor, McCarthy-Scarsbrook, Lee.
Hull FC: Shaul; Fonua, Griffin, Tuimavave, Talanoa; Kelly, Sneyd; Taylor, Houghton, Bowden, Washbrook, Minichiello, Manu.
Replacements: Watts, Connor, Thompson, Fash.
Referee: Phil Bentham
Two tries from Mark Percival helped St Helens earn a hard-fought Super League victory over Hull FC.