It might also help you to look at the problem in terms of 2D instead of 3D. Taking out the height/altitude component in your angle calculations reduces the problem to simple trigonometry.
So the basic algorithm becomes this (pseudocode):
// Assume Up is <0,1,0>
Vector2 target_position( target.X, target.Z ),
tower_position( tower.X, tower.Z );
// Quaternion construction using axis and angle.
double angle = tower_position.angle( target_position );
Quaternion tower_yaw( Vector(0,1,0), angle );
// Then concantonate the current rotation with the rotation you calculated, or you can interpolate with a slerp function if you wish.