(imo) Nothing beats FreeBSD's IPFW when it comes to features, but OpenBSD is still king of syntax/usability.
ipfw has better performance, too.
I guess what we need is some lex/yacc work to make a pf.conf syntax work with ipfw.
Largest issue is pf is "lastmatch wins" (copied from ipfilter, and a mistake that even Henning admits) and ipfw is “first match wins”.
pfSense makes all of rules "quick" to workaround this issue.
So without a ton of work, we could get the syntax (via an external package), but the semantics of existing pf.conf would be more difficult.
The rest is we would need the equivalent of pfsync.
A complex iptables ruleset is difficult to understand, while a pf.conf almost reads like prose.
Feature-wise, netfilter is richer, if only for the fact that there are more contributors. On the other hand, iptables and other frontends I've had the opportunity to use (ufw, firewalld) down right suck. Did I mention that most HOWTOs regarding iptables lead you down a wrong path, which is writing your ruleset as a shell script which calls the iptables / ip6tables binaries. If you fat finger a rule and run the script, you'll end up loading half the ruleset (which could be harmless, but you could very well lock yourself out a server if doing this remotely). PF rules are loaded atomically using the pfctl tool: either you get the whole new ruleset inplace, or you keep the old one. I believe the same behavior can be obtained with iptables-save/restore.
PF feels much more coherent and also has fantastic documentation. The OpenBSD FAQ as well as the pf.conf and pfctl cover most things you need to know regarding PF (there's also a book by Peter Hansteen called "The Book of PF" that is an excellent resource).
netfilter on the hand feels much more "stitched together". You want to configure IPv4 rules ? iptables. IPv6 ? ip6tables. You have rules tracking state? conntrack. The documentation around each of these tools is of varying quality. The one I'm having most trouble with is "tc", but that may because I don't grok queueing/traffic shaping/QoS yet. I have no experience with the latter on OpenBSD so I can not comment.
I don't trust any box running 300 out-of-date packages plus a PHP GUI, so my edge device is simply a dual-ethernet 8W device that runs OpenBSD with the following rules:
set skip on lo0
block all
pass out on en0 inet from en1:network to any nat-to (en0) // source NAT