Why does drupal_set_message function encode all html tags?
The messages added with drupal_set_message() are rendered in the page.tpl.php template file of the theme, if the file it is using one; otherwise, they are rendered through the template file defined from the System module.

By default, the System module and the core themes use the following code to print them.

&lt;?php print $messages; ?&gt;


There could be some HTML markup to wrap them, as in the Bartik theme, but that should not have the effect you are seeing.

  &lt;?php if ($messages): ?&gt;
    &lt;div id="messages"&gt;&lt;div class="section clearfix"&gt;
      &lt;?php print $messages; ?&gt;
    &lt;/div&gt;&lt;/div&gt; &lt;!-- /.section, /#messages --&gt;
  &lt;?php endif; ?&gt;


The way those messages are printed has not been changed from recent updates to Drupal core, so I would check the used theme and any installed (and enabled) modules to find out what is happening.

Apart from looking the page.tpl.php template file used from your theme, you should check the implementation of theme_status_messages() (which is normally called from template_preprocess_page()) done from the theme you are using, any preprocess function for theme_status_messages() (hook_preprocess_status_messages()), and any preprocess function used for the page.tpl.php template file (hook_preprocess_page()). Keep in mind that preprocess functions can be implemented by any module, or the theme used for the rendered page.

As side note, it is usually better to use t() and its placeholders, with drupal_set_message().  

drupal_set_message(t("!important. This not.", array('!important' =&gt; '&lt;b&gt;This is important&lt;/b&gt;')));


If you don't need to translate the message (e.g. because it is a debugging message), you could use [format_string()][5].

drupal_set_message(format_string("!important. This not.", array('!important' =&gt; '&lt;b&gt;This is important&lt;/b&gt;')));