NGUI's UIPanel will fight you over this. Take a look inside the UIPanel.UpdateLayers (line 1495) and comment out the
// NGUITools.SetChildLayer(cachedTransform, mLayer);
that should fix your problem. The problem is that UIPanel is very indiscriminate on what it changes the layer of - every child and subchild is just changed, no matter what layer it happens to be in, or if it's supposed to be rendered by something else. This is nice for consistency of the UI, but terrible if you're doing more tricky multi-layer work.