Born in Rochford, Holmes joined Chelmsford City's academy in 2004, after a short spell with Southend United, and made his debut on 9 November 2005 in a 3–1 Isthmian League Cup win against Horsham. Holmes made his full league debut for Chelmsford in August 2006, in a 1–1 draw against Bromley, also taking part in the club's impressive run in the FA Cup that year. He went on to become one of the club's top players, achieving promotion to the Conference South in 2007–08, a season in which he also won the club's player of the year award, scored 16 league goals. He also was linked with Championship side Crystal Palace. He remained a regular starter for the following two seasons. On 5 February 2008, Holmes was named in the England C squad for the match against Wales Semi-pro. On the 21st he made his international debut for the side. Holmes finished 2009–10 as City's top scorer, with 21 goals in the season. However, he was released in May 2010 after City allowed him to pursue his career at a higher level.
On 15 June 2010, Holmes signed a contract with Barnet. He made his debut on 7 August, against Chesterfield. Holmes scored his first goal for Barnet on 20 November, in a 4–1 win over Northampton Town. The 2010–11 season ended prematurely in January for Holmes as he was ruled out for the rest of the season with a foot injury. The 2011–12 season was more successful for Holmes. Under the management of Edgar Davids, Holmes' position was moved further towards the left wing, where he managed to score 10 goals. During the season, he consolidated his position in the Barnet first team. In an interview with Sky Sports that he believed he was better off playing as a second striker behind Izale McLeod. In 2012–13, he scored a hat-trick on 21 December 2012, in a 3–2 win against Burton Albion. In February 2013, he suffered the same foot injury, and was sidelined for the rest of the season. After Barnet's relegation, Holmes was linked to a number of clubs, the likes of Portsmouth, Leyton Orient, Gillingham, Burton Albion and Southend United providing competition for his signature.
Portsmouth
Holmes signed a two-year deal with Portsmouth on 21 June 2013, following the expiry of his contract at Barnet. He made his debut in a 4–1 home defeat to Oxford United on 3 August 2013. On 14 September, Holmes scored his first Pompey goal, in a 2–1 away victory over Burton Albion. Holmes received the fans' Player of the Season award in 2013–14.
On 2 January 2015, Holmes joined Northampton on an initial one-month loan deal. On 27 January 2015, after appearing in four matches and scoring once, he signed a 2½-year permanent deal with the club.
Holmes made a transfer request to Northampton on 15 June 2016 after repeated bids by Charlton and one day later after the 2 clubs eventually agreed a fee of £125,000, Holmes signed a two-year deal with the Addicks being the first signing for new manager Russell Slade. He scored his first goals for Charlton when he scored twice in a 3–0 win over Shrewsbury Town on 16 August 2016.
On 15 January 2018, Holmes made the switch from Charlton Athletic to Sheffield United for an undisclosed fee after a year and a half at the Valley, rejoining former Northampton manager Chris Wilder. He was transfer-listed by Sheffield United at the end of the 2018–19 season. On 4 May 2020, having been released at the end of his Sheffield United contract, Holmes stated that he would retire from professional football due to a back injury picked up whilst working on a building site in Horsham, during his time playing semi-professionally at Chelmsford City.
Oxford United (loan)
On 9 August 2018, Holmes signed for Oxford United on a season-long loan. He returned to his parent club in January 2019 for treatment after his appearances were limited by a back injury.
Gillingham (loan)
Holmes signed for Gillingham on loan on transfer deadline day in January 2019. He joined the club despite being injured, in an effort to regain fitness. On 24 April 2019, however, he returned to parent club Sheffield United after he had failed to regain fitness. He made no appearances for Gillingham during his three months at the club.