SampleLevel should work fine with wrapping; you just have to pass in a sampler state that sets AddressU and AddressV to Wrap.
You're not getting proper mipmapping this way, of course. You would need to do the texture lookup outside the loop in order for it to work. Regular texturing implicitly uses the UV derivatives to select the mip level. It seems you cannot take derivatives inside a loop or branch...that kinda sucks, but it's understandable. The hardware does derivatives by comparing values across nearby pixels, but if those nearby pixels might take a different execution path through the shader due to loops or branches, it doesn't have anything to compare to.
If you can calculate the UV derivatives yourself, you can use them with SampleGrad to get mipmapping back.