diff --git a/data/gui/chat_control.ui b/data/gui/chat_control.ui
index de3208afbc9fa94f54b7f9be20355858383ee499..8ab302dad1d07cb9c341a46538d7d8e06d88c9a3 100644
--- a/data/gui/chat_control.ui
+++ b/data/gui/chat_control.ui
@@ -5,7 +5,6 @@
   <object class="GtkVBox" id="chat_control_vbox">
     <property name="can_focus">True</property>
     <property name="border_width">3</property>
-    <property name="orientation">vertical</property>
     <property name="spacing">1</property>
     <child>
       <object class="GtkHBox" id="hbox3">
@@ -13,7 +12,6 @@
         <child>
           <object class="GtkVBox" id="vbox2">
             <property name="visible">True</property>
-            <property name="orientation">vertical</property>
             <child>
               <object class="GtkAlignment" id="alignment">
                 <property name="visible">True</property>
@@ -43,7 +41,6 @@
                             <property name="visible">True</property>
                             <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                             <property name="border_width">5</property>
-                            <property name="orientation">vertical</property>
                             <child>
                               <object class="GtkLabel" id="banner_name_label">
                                 <property name="visible">True</property>
@@ -195,7 +192,6 @@
             <child>
               <object class="GtkVBox" id="vbox106">
                 <property name="visible">True</property>
-                <property name="orientation">vertical</property>
                 <child>
                   <object class="GtkScrolledWindow" id="conversation_scrolledwindow">
                     <property name="height_request">60</property>
@@ -314,7 +310,6 @@
                   <object class="GtkVSeparator" id="vseparator1">
                     <property name="visible">True</property>
                     <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                    <property name="orientation">vertical</property>
                   </object>
                   <packing>
                     <property name="expand">False</property>
@@ -470,7 +465,6 @@
                   <object class="GtkVSeparator" id="vseparator3">
                     <property name="visible">True</property>
                     <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                    <property name="orientation">vertical</property>
                   </object>
                   <packing>
                     <property name="expand">False</property>
@@ -499,6 +493,14 @@
                     <property name="position">11</property>
                   </packing>
                 </child>
+                <child>
+                  <object class="GtkComboBox" id="label_selector">
+                    <property name="visible">True</property>
+                  </object>
+                  <packing>
+                    <property name="position">12</property>
+                  </packing>
+                </child>
                 <child>
                   <object class="GtkAlignment" id="alignment1">
                     <property name="visible">True</property>
@@ -508,7 +510,7 @@
                     </child>
                   </object>
                   <packing>
-                    <property name="position">12</property>
+                    <property name="position">13</property>
                   </packing>
                 </child>
                 <child>
@@ -555,7 +557,7 @@
                   </object>
                   <packing>
                     <property name="expand">False</property>
-                    <property name="position">13</property>
+                    <property name="position">14</property>
                   </packing>
                 </child>
               </object>
@@ -572,7 +574,6 @@
         <child>
           <object class="GtkVBox" id="audio_vbox">
             <property name="no_show_all">True</property>
-            <property name="orientation">vertical</property>
             <property name="spacing">6</property>
             <child>
               <object class="GtkLabel" id="label3">
diff --git a/data/gui/groupchat_control.ui b/data/gui/groupchat_control.ui
index f9ebc2798be25bb124260bd4d7d8683d778a7fdb..9c164c76ba994663ac482500ca73507513db8f34 100644
--- a/data/gui/groupchat_control.ui
+++ b/data/gui/groupchat_control.ui
@@ -5,7 +5,6 @@
   <object class="GtkVBox" id="groupchat_control_vbox">
     <property name="can_focus">True</property>
     <property name="border_width">3</property>
-    <property name="orientation">vertical</property>
     <child>
       <object class="GtkAlignment" id="alignment">
         <property name="visible">True</property>
@@ -35,7 +34,6 @@
                     <property name="visible">True</property>
                     <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                     <property name="border_width">5</property>
-                    <property name="orientation">vertical</property>
                     <child>
                       <object class="GtkLabel" id="banner_name_label">
                         <property name="visible">True</property>
@@ -133,7 +131,6 @@
           <object class="GtkVSeparator" id="vseparator2">
             <property name="visible">True</property>
             <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-            <property name="orientation">vertical</property>
           </object>
           <packing>
             <property name="expand">False</property>
@@ -233,7 +230,6 @@
           <object class="GtkVSeparator" id="vseparator4">
             <property name="visible">True</property>
             <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-            <property name="orientation">vertical</property>
           </object>
           <packing>
             <property name="expand">False</property>
@@ -269,6 +265,14 @@
             <property name="position">8</property>
           </packing>
         </child>
+        <child>
+          <object class="GtkComboBox" id="label_selector">
+            <property name="visible">True</property>
+          </object>
+          <packing>
+            <property name="position">9</property>
+          </packing>
+        </child>
         <child>
           <object class="GtkAlignment" id="alignment2">
             <property name="visible">True</property>
@@ -278,7 +282,7 @@
             </child>
           </object>
           <packing>
-            <property name="position">9</property>
+            <property name="position">10</property>
           </packing>
         </child>
         <child>
@@ -326,7 +330,7 @@
           <packing>
             <property name="expand">False</property>
             <property name="fill">False</property>
-            <property name="position">10</property>
+            <property name="position">11</property>
           </packing>
         </child>
       </object>
@@ -346,12 +350,10 @@
           <object class="GtkVBox" id="vbox108">
             <property name="width_request">0</property>
             <property name="visible">True</property>
-            <property name="orientation">vertical</property>
             <property name="spacing">6</property>
             <child>
               <object class="GtkVBox" id="vbox109">
                 <property name="visible">True</property>
-                <property name="orientation">vertical</property>
                 <property name="spacing">6</property>
                 <child>
                   <object class="GtkScrolledWindow" id="conversation_scrolledwindow">
diff --git a/src/chat_control.py b/src/chat_control.py
index e71a6d2a58af3d60f985693494522f5cb11b4c2a..d0028745e83202f4b6f1be2611b7b5846db46746 100644
--- a/src/chat_control.py
+++ b/src/chat_control.py
@@ -232,6 +232,29 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
     def status_url_clicked(self, widget, url):
         helpers.launch_browser_mailer('url', url)
 
+    def setup_seclabel(self, combo):
+        self.seclabel_combo = combo
+        self.seclabel_combo.hide()
+        self.seclabel_combo.set_no_show_all(True)
+        lb = gtk.ListStore(str)
+        self.seclabel_combo.set_model(lb)
+        cell = gtk.CellRendererText()
+        cell.set_property('xpad', 5) # padding for status text
+        self.seclabel_combo.pack_start(cell, True)
+        # text to show is in in first column of liststore
+        self.seclabel_combo.add_attribute(cell, 'text', 0)
+        if gajim.connections[self.account].seclabel_supported:
+            gajim.connections[self.account].seclabel_catalogue(self.contact.jid, self.on_seclabels_ready)
+
+    def on_seclabels_ready(self):
+        lb = self.seclabel_combo.get_model()
+        lb.clear()
+        for label in gajim.connections[self.account].seclabel_catalogues[self.contact.jid][2]:
+            lb.append([label])
+        self.seclabel_combo.set_active(0)
+        self.seclabel_combo.set_no_show_all(False)
+        self.seclabel_combo.show_all()
+
     def __init__(self, type_id, parent_win, widget_name, contact, acct,
     resource=None):
         # Undo needs this variable to know if space has been pressed.
@@ -721,6 +744,16 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
             self.drag_entered_conv = True
             self.conv_textview.tv.set_editable(True)
 
+    def get_seclabel(self):
+        label = None
+        if self.seclabel_combo is not None:
+            idx = self.seclabel_combo.get_active()
+            if idx != -1:
+                cat = gajim.connections[self.account].seclabel_catalogues[self.contact.jid]
+                lname = cat[2][idx]
+                label = cat[1][lname]
+        return label
+
     def send_message(self, message, keyID='', type_='chat', chatstate=None,
                     msg_id=None, composing_xep=None, resource=None, xhtml=None,
                     callback=None, callback_args=[], process_commands=True):
@@ -733,9 +766,11 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
         if process_commands and self.process_as_command(message):
             return
 
+        label = self.get_seclabel()
         MessageControl.send_message(self, message, keyID, type_=type_,
                 chatstate=chatstate, msg_id=msg_id, composing_xep=composing_xep,
                 resource=resource, user_nick=self.user_nick, xhtml=xhtml,
+                label=label,
                 callback=callback, callback_args=callback_args)
 
         # Record message history
@@ -769,7 +804,7 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
                     other_tags_for_name=[], other_tags_for_time=[],
                     other_tags_for_text=[], count_as_new=True, subject=None,
                     old_kind=None, xhtml=None, simple=False, xep0184_id=None,
-                    graphics=True):
+                    graphics=True, displaymarking=None):
         """
         Print 'chat' type messages
         """
@@ -781,7 +816,8 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
             end = True
         textview.print_conversation_line(text, jid, kind, name, tim,
                 other_tags_for_name, other_tags_for_time, other_tags_for_text,
-                subject, old_kind, xhtml, simple=simple, graphics=graphics)
+                subject, old_kind, xhtml, simple=simple, graphics=graphics,
+                displaymarking=displaymarking)
 
         if xep0184_id is not None:
             textview.show_xep0184_warning(xep0184_id)
@@ -1429,6 +1465,7 @@ class ChatControl(ChatControlBase):
             session = gajim.connections[self.account].find_controlless_session(
                     self.contact.jid, resource)
 
+        self.setup_seclabel(self.xml.get_object('label_selector'))
         if session:
             session.control = self
             self.session = session
@@ -2048,20 +2085,23 @@ class ChatControl(ChatControlBase):
                 gobject.source_remove(self.possible_inactive_timeout_id)
                 self._schedule_activity_timers()
 
-        def _on_sent(id_, contact, message, encrypted, xhtml):
+        def _on_sent(id_, contact, message, encrypted, xhtml, label):
             if contact.supports(NS_RECEIPTS) and gajim.config.get_per('accounts',
             self.account, 'request_receipt'):
                 xep0184_id = id_
             else:
                 xep0184_id = None
-
+            if label:
+                displaymarking = label.getTag('displaymarking')
+            else:
+                displaymarking = None
             self.print_conversation(message, self.contact.jid, encrypted=encrypted,
-                    xep0184_id=xep0184_id, xhtml=xhtml)
+                    xep0184_id=xep0184_id, xhtml=xhtml, displaymarking=displaymarking)
 
         ChatControlBase.send_message(self, message, keyID, type_='chat',
                 chatstate=chatstate_to_send, composing_xep=composing_xep,
                 xhtml=xhtml, callback=_on_sent,
-                callback_args=[contact, message, encrypted, xhtml],
+                callback_args=[contact, message, encrypted, xhtml, self.get_seclabel()],
                 process_commands=process_commands)
 
     def check_for_possible_paused_chatstate(self, arg):
@@ -2150,7 +2190,8 @@ class ChatControl(ChatControlBase):
                         self.session.is_loggable(), self.session and self.session.verified_identity)
 
     def print_conversation(self, text, frm='', tim=None, encrypted=False,
-                    subject=None, xhtml=None, simple=False, xep0184_id=None):
+                    subject=None, xhtml=None, simple=False, xep0184_id=None,
+                    displaymarking=None):
         """
         Print a line in the conversation
 
@@ -2213,7 +2254,7 @@ class ChatControl(ChatControlBase):
                         xhtml = '<body xmlns="%s">%s</body>' % (NS_XHTML, xhtml)
         ChatControlBase.print_conversation_line(self, text, kind, name, tim,
                 subject=subject, old_kind=self.old_msg_kind, xhtml=xhtml,
-                simple=simple, xep0184_id=xep0184_id)
+                simple=simple, xep0184_id=xep0184_id, displaymarking=displaymarking)
         if text.startswith('/me ') or text.startswith('/me\n'):
             self.old_msg_kind = None
         else:
@@ -2660,8 +2701,12 @@ class ChatControl(ChatControlBase):
                 kind = 'info'
             else:
                 kind = 'print_queue'
+            dm = None
+            if len(data) > 10:
+                dm = data[10]
             self.print_conversation(data[0], kind, tim = data[3],
-                    encrypted = data[4], subject = data[1], xhtml = data[7])
+                    encrypted = data[4], subject = data[1], xhtml = data[7],
+                    displaymarking=dm)
             if len(data) > 6 and isinstance(data[6], int):
                 message_ids.append(data[6])
 
diff --git a/src/common/connection.py b/src/common/connection.py
index d9dbb961d2755997d6a079744cd7ca105b2805e9..336516fdfc587dd847965f6a3476341f264b2472 100644
--- a/src/common/connection.py
+++ b/src/common/connection.py
@@ -135,6 +135,9 @@ class CommonConnection:
         self.blocked_groups = []
         self.blocked_all = False
 
+        self.seclabel_supported = False
+        self.seclabel_catalogues = {}
+
         self.pep_supported = False
         self.pep = {}
         # Do we continue connection when we get roster (send presence,get vcard..)
@@ -239,7 +242,7 @@ class CommonConnection:
     def _prepare_message(self, jid, msg, keyID, type_='chat', subject='',
     chatstate=None, msg_id=None, composing_xep=None, resource=None,
     user_nick=None, xhtml=None, session=None, forward_from=None, form_node=None,
-    original_message=None, delayed=None, callback=None):
+    label=None, original_message=None, delayed=None, callback=None):
         if not self.connection or self.connected < 2:
             return 1
         try:
@@ -287,14 +290,14 @@ class CommonConnection:
                             else:
                                 self._message_encrypted_cb(output, type_, msg, msgtxt,
                                         original_message, fjid, resource, jid, xhtml,
-                                        subject, chatstate, composing_xep, forward_from,
+                                        subject, chatstate, composing_xep, label, forward_from,
                                         delayed, session, form_node, user_nick, keyID,
                                         callback)
                         self.dispatch('GPG_ALWAYS_TRUST', _on_always_trust)
                     else:
                         self._message_encrypted_cb(output, type_, msg, msgtxt,
                                 original_message, fjid, resource, jid, xhtml, subject,
-                                chatstate, composing_xep, forward_from, delayed, session,
+                                chatstate, composing_xep, label, forward_from, delayed, session,
                                 form_node, user_nick, keyID, callback)
                 gajim.thread_interface(encrypt_thread, [msg, keyID, False],
                         _on_encrypted, [])
@@ -302,15 +305,15 @@ class CommonConnection:
 
             self._message_encrypted_cb(('', error), type_, msg, msgtxt,
                     original_message, fjid, resource, jid, xhtml, subject, chatstate,
-                    composing_xep, forward_from, delayed, session, form_node, user_nick,
+                    composing_xep, label, forward_from, delayed, session, form_node, user_nick,
                     keyID, callback)
 
         self._on_continue_message(type_, msg, msgtxt, original_message, fjid,
                 resource, jid, xhtml, subject, msgenc, keyID, chatstate, composing_xep,
-                forward_from, delayed, session, form_node, user_nick, callback)
+                label, forward_from, delayed, session, form_node, user_nick, callback)
 
     def _message_encrypted_cb(self, output, type_, msg, msgtxt, original_message,
-    fjid, resource, jid, xhtml, subject, chatstate, composing_xep, forward_from,
+    fjid, resource, jid, xhtml, subject, chatstate, composing_xep, label, forward_from,
     delayed, session, form_node, user_nick, keyID, callback):
         msgenc, error = output
 
@@ -323,7 +326,7 @@ class CommonConnection:
                         ' (' + msgtxt + ')'
             self._on_continue_message(type_, msg, msgtxt, original_message, fjid,
                     resource, jid, xhtml, subject, msgenc, keyID, chatstate,
-                    composing_xep, forward_from, delayed, session, form_node, user_nick,
+                    composing_xep, label, forward_from, delayed, session, form_node, user_nick,
                     callback)
             return
         # Encryption failed, do not send message
@@ -332,6 +335,7 @@ class CommonConnection:
 
     def _on_continue_message(self, type_, msg, msgtxt, original_message, fjid,
     resource, jid, xhtml, subject, msgenc, keyID, chatstate, composing_xep,
+    label,
     forward_from, delayed, session, form_node, user_nick, callback):
         if type_ == 'chat':
             msg_iq = common.xmpp.Message(to=fjid, body=msgtxt, typ=type_,
@@ -348,6 +352,8 @@ class CommonConnection:
 
         if form_node:
             msg_iq.addChild(node=form_node)
+        if label:
+            msg_iq.addChild(node=label)
 
         # XEP-0172: user_nickname
         if user_nick:
@@ -1605,7 +1611,7 @@ class Connection(CommonConnection, ConnectionHandlers):
 
     def send_message(self, jid, msg, keyID, type_='chat', subject='',
     chatstate=None, msg_id=None, composing_xep=None, resource=None,
-    user_nick=None, xhtml=None, session=None, forward_from=None, form_node=None,
+    user_nick=None, xhtml=None, label=None, session=None, forward_from=None, form_node=None,
     original_message=None, delayed=None, callback=None, callback_args=[],
     now=False):
 
@@ -1622,7 +1628,8 @@ class Connection(CommonConnection, ConnectionHandlers):
 
         self._prepare_message(jid, msg, keyID, type_=type_, subject=subject,
                 chatstate=chatstate, msg_id=msg_id, composing_xep=composing_xep,
-                resource=resource, user_nick=user_nick, xhtml=xhtml, session=session,
+                resource=resource, user_nick=user_nick, xhtml=xhtml, label=label,
+                session=session,
                 forward_from=forward_from, form_node=form_node,
                 original_message=original_message, delayed=delayed, callback=cb)
 
@@ -1830,6 +1837,15 @@ class Connection(CommonConnection, ConnectionHandlers):
         iq2.addChild(name='gajim', namespace='gajim:prefs')
         self.connection.send(iq)
 
+    def seclabel_catalogue(self, to, callback):
+        if not gajim.account_is_connected(self.name):
+            return
+        self.seclabel_catalogue_request(to, callback)
+        iq = common.xmpp.Iq(typ='get')
+        iq2 = iq.addChild(name='catalog', namespace=common.xmpp.NS_SECLABEL_CATALOG)
+        iq2.setAttr('to', to)
+        self.connection.send(iq)
+
     def _request_bookmarks_xml(self):
         if not gajim.account_is_connected(self.name):
             return
@@ -2041,13 +2057,15 @@ class Connection(CommonConnection, ConnectionHandlers):
                 t.setTagData('password', password)
         self.connection.send(p)
 
-    def send_gc_message(self, jid, msg, xhtml = None):
+    def send_gc_message(self, jid, msg, xhtml = None, label = None):
         if not gajim.account_is_connected(self.name):
             return
         if not xhtml and gajim.config.get('rst_formatting_outgoing_messages'):
             from common.rst_xhtml_generator import create_xhtml
             xhtml = create_xhtml(msg)
         msg_iq = common.xmpp.Message(jid, msg, typ = 'groupchat', xhtml = xhtml)
+        if label is not None:
+            msg_iq.addChild(node = label)
         self.connection.send(msg_iq)
         self.dispatch('MSGSENT', (jid, msg))
 
diff --git a/src/common/connection_handlers.py b/src/common/connection_handlers.py
index d60e14b5ef0e1bad4ba6d2b5694469c699d8a029..a42f17cbc6517289eaf37f4351e60a3356520d82 100644
--- a/src/common/connection_handlers.py
+++ b/src/common/connection_handlers.py
@@ -341,6 +341,8 @@ class ConnectionDisco:
                 if features.__contains__(common.xmpp.NS_GMAILNOTIFY):
                     gajim.gmail_domains.append(jid)
                     self.request_gmail_notifications()
+                if features.__contains__(common.xmpp.NS_SECLABEL):
+                    self.seclabel_supported = True
                 for identity in identities:
                     if identity['category'] == 'pubsub' and identity.get('type') == \
                     'pep':
@@ -1071,6 +1073,33 @@ ConnectionCaps, ConnectionHandlersBase, ConnectionJingle):
                     annotation = note.getData()
                     self.annotations[jid] = annotation
 
+    def _SecLabelCB(self, con, iq_obj):
+        """
+        Security Label callback, used for catalogues.
+        """
+        log.debug('SecLabelCB')
+        query = iq_obj.getTag('catalog')
+        to = query.getAttr('to')
+        items = query.getTags('securitylabel')
+        labels = {}
+        ll = []
+        for item in items:
+            label = item.getTag('displaymarking').getData()
+            labels[label] = item
+            ll.append(label)
+        if to not in self.seclabel_catalogues:
+            self.seclabel_catalogues[to] = [[], None, None]
+        self.seclabel_catalogues[to][1] = labels
+        self.seclabel_catalogues[to][2] = ll
+        for callback in self.seclabel_catalogues[to][0]:
+            callback()
+        self.seclabel_catalogues[to][0] = []
+
+    def seclabel_catalogue_request(self, to, callback):
+        if to not in self.seclabel_catalogues:
+            self.seclabel_catalogues[to] = [[], None, None]
+        self.seclabel_catalogues[to][0].append(callback)
+
     def _parse_bookmarks(self, storage, storage_type):
         """
         storage_type can be 'pubsub' or 'xml' to tell from where we got bookmarks
@@ -1618,12 +1647,15 @@ ConnectionCaps, ConnectionHandlersBase, ConnectionJingle):
                     self.dispatch('GC_CONFIG_CHANGE', (jid, statusCode))
             return
 
-        # Ignore message from room in which we are not
+        displaymarking = None
+        seclabel = msg.getTag('securitylabel')
+        if seclabel and seclabel.getNamespace() == common.xmpp.NS_SECLABEL:
+            displaymarking = seclabel.getTag('displaymarking')        # Ignore message from room in which we are not
         if jid not in self.last_history_time:
             return
 
         self.dispatch('GC_MSG', (frm, msgtxt, tim, has_timestamp, msg.getXHTML(),
-                statusCode))
+                statusCode, displaymarking))
 
         tim_int = int(float(mktime(tim)))
         if gajim.config.should_log(self.name, jid) and not \
@@ -2302,6 +2334,8 @@ ConnectionCaps, ConnectionHandlersBase, ConnectionJingle):
                 common.xmpp.NS_MUC_ADMIN)
         con.RegisterHandler('iq', self._PrivateCB, 'result',
                 common.xmpp.NS_PRIVATE)
+        con.RegisterHandler('iq', self._SecLabelCB, 'result',
+                common.xmpp.NS_SECLABEL_CATALOG)
         con.RegisterHandler('iq', self._HttpAuthCB, 'get',
                 common.xmpp.NS_HTTP_AUTH)
         con.RegisterHandler('iq', self._CommandExecuteCB, 'set',
diff --git a/src/common/gajim.py b/src/common/gajim.py
index 214f5e369d651324d40ae12a785fe42ac0496c31..a44029de5016bc66fe60c73eb00f27e7eabf2232 100644
--- a/src/common/gajim.py
+++ b/src/common/gajim.py
@@ -193,7 +193,7 @@ gajim_common_features = [xmpp.NS_BYTESTREAM, xmpp.NS_SI, xmpp.NS_FILE,
         'jabber:iq:gateway', xmpp.NS_LAST, xmpp.NS_PRIVACY, xmpp.NS_PRIVATE,
         xmpp.NS_REGISTER, xmpp.NS_VERSION, xmpp.NS_DATA, xmpp.NS_ENCRYPTED, 'msglog',
         'sslc2s', 'stringprep', xmpp.NS_PING, xmpp.NS_TIME_REVISED, xmpp.NS_SSN,
-        xmpp.NS_MOOD, xmpp.NS_ACTIVITY, xmpp.NS_NICK, xmpp.NS_ROSTERX]
+        xmpp.NS_MOOD, xmpp.NS_ACTIVITY, xmpp.NS_NICK, xmpp.NS_ROSTERX, xmpp.NS_SECLABEL]
 
 # Optional features gajim supports per account
 gajim_optional_features = {}
diff --git a/src/common/xmpp/protocol.py b/src/common/xmpp/protocol.py
index a14eb8dca7d1972419040d0d1c75ffbcf6cd39bb..01dd49d86b36ddbaf7449700c37d24286fe48cac 100644
--- a/src/common/xmpp/protocol.py
+++ b/src/common/xmpp/protocol.py
@@ -100,6 +100,8 @@ NS_ROSTERX        ='http://jabber.org/protocol/rosterx'
 NS_ROSTER_VER    ='urn:xmpp:features:rosterver'               # XEP-0273
 NS_RPC            ='jabber:iq:rpc'                                                                              # XEP-0009
 NS_SASL          ='urn:ietf:params:xml:ns:xmpp-sasl'
+NS_SECLABEL         ='urn:xmpp:sec-label:0'
+NS_SECLABEL_CATALOG ='urn:xmpp:sec-label:catalog:0'
 NS_SEARCH          ='jabber:iq:search'
 NS_SERVER          ='jabber:server'
 NS_SESSION        ='urn:ietf:params:xml:ns:xmpp-session'
diff --git a/src/conversation_textview.py b/src/conversation_textview.py
index a96c41b677d6826ddc1c37dd29eda8da76e14c4c..46e60dfeef9c183cebcd3626c09b142bce98fac2 100644
--- a/src/conversation_textview.py
+++ b/src/conversation_textview.py
@@ -326,6 +326,7 @@ class ConversationTextview(gobject.GObject):
         tag.set_property('underline', pango.UNDERLINE_SINGLE)
 
         buffer_.create_tag('focus-out-line', justification = gtk.JUSTIFY_CENTER)
+        self.displaymarking_tags = {}
 
         tag = buffer_.create_tag('xep0184-warning')
 
@@ -1173,7 +1174,7 @@ class ConversationTextview(gobject.GObject):
     def print_conversation_line(self, text, jid, kind, name, tim,
                     other_tags_for_name=[], other_tags_for_time=[],
                     other_tags_for_text=[], subject=None, old_kind=None, xhtml=None,
-                    simple=False, graphics=True):
+                    simple=False, graphics=True, displaymarking=None):
         """
         Print 'chat' type messages
         """
@@ -1238,6 +1239,9 @@ class ConversationTextview(gobject.GObject):
                     tim_format = self.get_time_to_show(tim)
                 buffer_.insert_with_tags_by_name(end_iter, tim_format + '\n',
                         'time_sometimes')
+        # If there's a displaymarking, print it here.
+        if displaymarking:
+            self.print_displaymarking(displaymarking)
         # kind = info, we print things as if it was a status: same color, ...
         if kind in ('error', 'info'):
             kind = 'status'
@@ -1309,6 +1313,19 @@ class ConversationTextview(gobject.GObject):
         elif text.startswith('/me ') or text.startswith('/me\n'):
             return kind
 
+    def print_displaymarking(self, displaymarking):
+        bgcolor = displaymarking.getAttr('bgcolor') or '#FFF'
+        fgcolor = displaymarking.getAttr('fgcolor') or '#000'
+        text = displaymarking.getData()
+        if text:
+            buffer_ = self.tv.get_buffer()
+            end_iter = buffer_.get_end_iter()
+            tag = self.displaymarking_tags.setdefault(bgcolor + '/' + fgcolor,
+                buffer_.create_tag(None, background=bgcolor, foreground=fgcolor))
+            buffer_.insert_with_tags(end_iter, '[' + text + ']', tag)
+            end_iter = buffer_.get_end_iter()
+            buffer_.insert_with_tags(end_iter, ' ')
+
     def print_name(self, name, kind, other_tags_for_name):
         if name:
             buffer_ = self.tv.get_buffer()
diff --git a/src/groupchat_control.py b/src/groupchat_control.py
index bf78159db2be80c090a038c24b1b2fe60413dd9c..b604c8fba3eb06798f64fa42bb9c28baeab7959c 100644
--- a/src/groupchat_control.py
+++ b/src/groupchat_control.py
@@ -385,6 +385,8 @@ class GroupchatControl(ChatControlBase):
         column.set_visible(False)
         self.list_treeview.set_expander_column(column)
 
+        self.setup_seclabel(self.xml.get_object('label_selector'))
+
         gajim.gc_connected[self.account][self.room_jid] = False
         # disable win, we are not connected yet
         ChatControlBase.got_disconnected(self)
@@ -785,30 +787,30 @@ class GroupchatControl(ChatControlBase):
         menu.destroy()
 
     def on_message(self, nick, msg, tim, has_timestamp=False, xhtml=None,
-    status_code=[]):
+    status_code=[], displaymarking=None):
         if '100' in status_code:
             # Room is not anonymous
             self.is_anonymous = False
         if not nick:
             # message from server
-            self.print_conversation(msg, tim=tim, xhtml=xhtml)
+            self.print_conversation(msg, tim=tim, xhtml=xhtml, displaymarking=displaymarking)
         else:
             # message from someone
             if has_timestamp:
                 # don't print xhtml if it's an old message.
                 # Like that xhtml messages are grayed too.
-                self.print_old_conversation(msg, nick, tim, None)
+                self.print_old_conversation(msg, nick, tim, None, displaymarking=displaymarking)
             else:
-                self.print_conversation(msg, nick, tim, xhtml)
+                self.print_conversation(msg, nick, tim, xhtml, displaymarking=displaymarking)
 
     def on_private_message(self, nick, msg, tim, xhtml, session, msg_id=None,
-    encrypted=False):
+    encrypted=False, displaymarking=None):
         # Do we have a queue?
         fjid = self.room_jid + '/' + nick
         no_queue = len(gajim.events.get_events(self.account, fjid)) == 0
 
         event = gajim.events.create_event('pm', (msg, '', 'incoming', tim,
-            encrypted, '', msg_id, xhtml, session))
+            encrypted, '', msg_id, xhtml, session, displaymarking))
         gajim.events.add_event(self.account, fjid, event)
 
         autopopup = gajim.config.get('autopopup')
@@ -851,7 +853,8 @@ class GroupchatControl(ChatControlBase):
             role_iter = model.iter_next(role_iter)
         return None
 
-    def print_old_conversation(self, text, contact='', tim=None, xhtml = None):
+    def print_old_conversation(self, text, contact='', tim=None, xhtml = None,
+        displaymarking=None):
         if isinstance(text, str):
             text = unicode(text, 'utf-8')
         if contact:
@@ -867,10 +870,11 @@ class GroupchatControl(ChatControlBase):
             small_attr = []
         ChatControlBase.print_conversation_line(self, text, kind, contact, tim,
             small_attr, small_attr + ['restored_message'],
-            small_attr + ['restored_message'], count_as_new=False, xhtml=xhtml)
+            small_attr + ['restored_message'], count_as_new=False, xhtml=xhtml,
+            displaymarking=displaymarking)
 
     def print_conversation(self, text, contact='', tim=None, xhtml=None,
-    graphics=True):
+    graphics=True, displaymarking=None):
         """
         Print a line in the conversation
 
@@ -937,7 +941,7 @@ class GroupchatControl(ChatControlBase):
 
         ChatControlBase.print_conversation_line(self, text, kind, contact, tim,
             other_tags_for_name, [], other_tags_for_text, xhtml=xhtml,
-            graphics=graphics)
+            graphics=graphics, displaymarking=displaymarking)
 
     def get_nb_unread(self):
         type_events = ['printed_marked_gc_msg']
@@ -1588,12 +1592,13 @@ class GroupchatControl(ChatControlBase):
         if not message:
             return
 
+        label = self.get_seclabel()
         if message != '' or message != '\n':
             self.save_sent_message(message)
 
             # Send the message
             gajim.connections[self.account].send_gc_message(self.room_jid,
-                    message, xhtml=xhtml)
+                    message, xhtml=xhtml, label=label)
             self.msg_textview.get_buffer().set_text('')
             self.msg_textview.grab_focus()
 
diff --git a/src/gui_interface.py b/src/gui_interface.py
index 769b14deddc9e5ab42d8e65206b7f4ab3156935b..369c27637e9717426ba2da9b142829940b9a96d0 100644
--- a/src/gui_interface.py
+++ b/src/gui_interface.py
@@ -956,7 +956,7 @@ class Interface:
 
     def handle_event_gc_msg(self, account, array):
         # ('GC_MSG', account, (jid, msg, time, has_timestamp, htmlmsg,
-        # [status_codes]))
+        # [status_codes], displaymarking))
         jids = array[0].split('/', 1)
         room_jid = jids[0]
 
@@ -980,7 +980,7 @@ class Interface:
             # message from someone
             nick = jids[1]
 
-        gc_control.on_message(nick, msg, array[2], array[3], xhtml, array[5])
+        gc_control.on_message(nick, msg, array[2], array[3], xhtml, array[5], displaymarking=array[6])
 
         if self.remote_ctrl:
             highlight = gc_control.needs_visual_notification(msg)
diff --git a/src/message_control.py b/src/message_control.py
index 5dfce76eb8a038a4713ec3cba2955469f00de01c..d09cb446be1efa1328d01f1505244ef69153bb92 100644
--- a/src/message_control.py
+++ b/src/message_control.py
@@ -208,7 +208,7 @@ class MessageControl:
 
     def send_message(self, message, keyID='', type_='chat', chatstate=None,
                     msg_id=None, composing_xep=None, resource=None, user_nick=None,
-                    xhtml=None, callback=None, callback_args=[]):
+                    xhtml=None, label=None, callback=None, callback_args=[]):
         # Send the given message to the active tab.
         # Doesn't return None if error
         jid = self.contact.jid
@@ -241,5 +241,5 @@ class MessageControl:
         conn.send_message(jid, message, keyID, type_=type_, chatstate=chatstate,
                 msg_id=msg_id, composing_xep=composing_xep, resource=self.resource,
                 user_nick=user_nick, session=self.session,
-                original_message=original_message, xhtml=xhtml, callback=callback,
+                original_message=original_message, xhtml=xhtml, label=label, callback=callback,
                 callback_args=callback_args)
diff --git a/src/session.py b/src/session.py
index 25889e1f0b8fa12757ac38b9c6432c1e75b9b028..4af87c20b78cf6f0453e7c8e8e88bd790e631f04 100644
--- a/src/session.py
+++ b/src/session.py
@@ -95,6 +95,8 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
             self.resource = resource
             if self.control and self.control.resource:
                 self.control.change_resource(self.resource)
+        seclabel = None
+        displaymarking = None
 
         if not msg_type or msg_type not in ('chat', 'groupchat', 'error'):
             msg_type = 'normal'
@@ -113,7 +115,9 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
                 break
 
         composing_xep, chatstate = self.get_chatstate(msg, msgtxt)
-
+        seclabel = msg.getTag('securitylabel')
+        if seclabel and seclabel.getNamespace() == common.xmpp.NS_SECLABEL:
+            displaymarking = seclabel.getTag('displaymarking')
         xhtml = msg.getXHTML()
 
         if msg_type == 'chat':
@@ -236,15 +240,15 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
             if self.control:
                 # print if a control is open
                 self.control.print_conversation(msgtxt, tim=tim, xhtml=xhtml,
-                        encrypted=encrypted)
+                        encrypted=encrypted, displaymarking=displaymarking)
             else:
                 # otherwise pass it off to the control to be queued
                 groupchat_control.on_private_message(nickname, msgtxt, tim,
-                        xhtml, self, msg_id=msg_id, encrypted=encrypted)
+                        xhtml, self, msg_id=msg_id, encrypted=encrypted, displaymarking=displaymarking)
         else:
             self.roster_message(jid, msgtxt, tim, encrypted, msg_type,
                     subject, resource, msg_id, user_nick, advanced_notif_num,
-                    xhtml=xhtml, form_node=form_node)
+                    xhtml=xhtml, form_node=form_node, displaymarking=displaymarking)
 
             nickname = gajim.get_name_from_jid(self.conn.name, jid)
 
@@ -270,7 +274,7 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
 
     def roster_message(self, jid, msg, tim, encrypted=False, msg_type='',
                     subject=None, resource='', msg_id=None, user_nick='',
-                    advanced_notif_num=None, xhtml=None, form_node=None):
+                    advanced_notif_num=None, xhtml=None, form_node=None, displaymarking=None):
         """
         Display the message or show notification in the roster
         """
@@ -334,7 +338,7 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
         if msg_type == 'normal' and popup: # it's single message to be autopopuped
             dialogs.SingleMessageWindow(self.conn.name, contact.jid,
                     action='receive', from_whom=jid, subject=subject, message=msg,
-                    resource=resource, session=self, form_node=form_node)
+                    resource=resource, session=self, form_node=form_node, displaymarking=displaymarking)
             return
 
         # We print if window is opened and it's not a single message
@@ -345,7 +349,7 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
                 typ = 'error'
 
             self.control.print_conversation(msg, typ, tim=tim, encrypted=encrypted,
-                    subject=subject, xhtml=xhtml)
+                    subject=subject, xhtml=xhtml, displaymarking=displaymarking)
 
             if msg_id:
                 gajim.logger.set_read_messages([msg_id])
@@ -366,7 +370,7 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
                 contact)
 
         event = gajim.events.create_event(type_, (msg, subject, msg_type, tim,
-                encrypted, resource, msg_id, xhtml, self, form_node),
+                encrypted, resource, msg_id, xhtml, self, form_node, displaymarking),
                 show_in_roster=show_in_roster, show_in_systray=show_in_systray)
 
         gajim.events.add_event(self.conn.name, fjid, event)