With BCEL, you have to learn details of Java bytecode
for transforming a class file. On the other hand,
with Javassist, you don't have to.
Javassist allows you to transform a class file with
source-level abstraction. For example, you can
give a Java statement to Javassist, which can
compile the statement and insert in a method body.
However, if you love Java bytecode, Javassist allows
you to directly modify it as BCEL does. :)
BCEL is much more low-level. For a while, Tapestry (http://jakarta.apache.org/tapestry) was using BCEL. Tapestry often creates subclasses with new properties in them (new fields and accessor methods).
We just stripped out BCEL and replaced it with Javassist, and have been busy adding features that we couldn't easily accomplish in BCEL.
There's a small number of things you can't do directly with Javassist (or, perhaps, I just haven't figure out how to do them), but for the kind of stuff Tapestry needs, it's a huge win.