Williams joined Barnsley on 22 December 2014.[4][5] He made his professional debut on 26 December 2014 in a 1–0 defeat to Preston North End.[6] On 29 May 2016, Williams featured in Barnsley's 3–1 League One play-off final victory over Millwall, achieving promotion to the EFL Championship.[7] However, on 15 June 2016, Williams was released by the club.[8]
Milton Keynes Dons
On 28 June 2016, Williams returned to Milton Keynes Dons on a two-year deal having previously played for the club's academy side.[9] He made his debut for the club on 6 August 2016 away to Shrewsbury Town, coming on as a 90th-minute substitute,[10] and on 18 October 2016 scored his first goal for the club with a 23rd-minute header in a 3–3 home draw with Bristol Rovers.[11] At the end of his first season back at the club, Williams was awarded both the club's 2016–17 Player of the Year and Players' Player of the Year awards,[12] and in July 2017 signed a new long-term deal keeping him at the club until June 2020.[13]
Bristol Rovers
On 21 January 2021 with just six months remaining on his contract, Williams joined Bristol Rovers for an undisclosed fee.[14] He made his debut that weekend in a 2–0 away defeat to Oxford United, coming off of the bench to replace Abu Ogogo in the 67' minute.[15]
Cambridge United
On 25 June 2021, Williams joined League One side Cambridge United on a free transfer, returning to the division following Bristol Rovers' relegation.[16] He made his Cambridge debut against Oxford United in a 1-1 draw.