I see many people prefer to use pre_get_posts hook instead of query_posts
Yay!
So pre_get_posts filters a WP_Query object which means anything you could do via query_posts() you can do via $query->set() and $query->get(). In particular we can make use of the meta_query attribute (see Codex):
$meta_query = array(
array(
'key'=>'featured',
'value'=>'yes',
'compare'=>'!=',
),
);
$query->set('meta_query',$meta_query);
But.. this replaces the original ‘meta query’ (if it had one). So unless you want to completely replace the original meta query, I suggest:
//Get original meta query
$meta_query = $query->get('meta_query');
//Add our meta query to the original meta queries
$meta_query[] = array(
'key'=>'featured',
'value'=>'yes',
'compare'=>'!=',
);
$query->set('meta_query',$meta_query);
This way we add our meta query alongside existing meta queries.
You may/may not want to set the relation property of $meta_query to AND or OR (to return posts that satisfy all, or at least one, meta queries).
* Note: This type of query will return posts with the ‘featured’ meta key, but whose value is not yes. It will not include posts where the ‘featured’ meta key doesn’t exist. You’ll be able to do this in 3.5.