Was focusing on getting the data there as the extra header is a presentation aspect and not really interesting, so while you could do a pivot i think the cross apply is more agile in this circumstance. Especially because of it's inherent ability to simply add cross applies based on data if a dynamic query version is chosen.
declare @grp table(
facid int
)
insert into @grp(facid)
(select distinct facid from @tbl)
select facid, c.*, d.*, e.*
from @grp a
cross apply(
select q1, q2, q3 from @tbl b where b.batchid = 'B001' and a.facid = b.facid
) c
cross apply(
select q1, q2, q3 from @tbl b where b.batchid = 'B002' and a.facid = b.facid
) d
cross apply(
select q1, q2, q3 from @tbl b where b.batchid = 'B003' and a.facid = b.facid
) e