I realize this is really old, but I thought I would answer this for any future readers...
pwelch appears to apply a broadband/random window correction factor. This means that the amplitude of a discrete sinusoidal will not be correct, but it can be corrected for by the ratio of the discrete signal correction factor over the random broadband/random factor. This is not discussed in the documentation anywhere, but that is what comes out of pwelch.
If you input a window function besides the default (hamming) it still applies the correction factor so it must calculate the factor from the weighted function the goes in as the "window" input, without knowing the name of the function being used. You could make up a function and I think it would still apply the correction factor.
For example, the broadband correction factor for a hanning window is 8/3. for a discrete signal the correction factor is 4.0 (2.0 on the amplitude spectrum). So multiplying the PSD by 4/(8/3) = 1.5 will give you the correct amplitude of a sinusoidal.
This can be demonstrated by the script below:
fs=1000; t=[1/fs:1/fs:100]'; disp(['input signal (rms):' num2str(20/sqrt(2))]); x=randn(length(t),1)*10+20*cos(2.*pi.*56*t); nfft=1000; p=pwelch(x,hanning(nfft),nfft/2,nfft,fs); disp(['calculated amplitude (rms):' num2str(sqrt(p(57)*1.5))]); % or can just sum the 56 Hz bin with the adjacent bins where the window spilled into: disp(['calculated amplitude (rms):' num2str(sqrt(sum(p(56:58))))]);