Portably:

 sed '
 s/.*/ & /; # add a leading and trailing space
 :1
 s/\([[:blank:]]541[^[:blank:]]\{2\}\)\([^[:blank:]]\{5\}[[:blank:]]\)/\19\2/g
 # replace in a loop until there is no more match
 t1
 # remove the blanks we added earlier:
 s/^ //;s/ $//'

You can avoid the temporary adding of the leading and trailing spaces by looking for the occurrence of that 10 non-blank string at the beginning or the end of the list in addition to following/preceding a blank. That can be done POSIXly with one regexp, but that's a bit unwieldy:

 sed '
 :1
 s/^\(\(.*[[:blank:]]\)\{0,1\}541[^[:blank:]]\{2\}\)\([^[:blank:]]\{5\}\([[:blank:]].*\)\{0,1\}\)$/\19\3/
 t1'

With `perl`, using look-around operators:

 perl -lpe 's/((?<!\H)541\H\H)(\H{5})(?!\H)/${1}9$2/g'

Or processing words one by-one:

 perl -lpe 's{\H+}{$&=~s/^541..\K.{5}$/9$&/r}ge'

(`\K` and the `r` substitution flag require a relatively recent version of `perl`).