diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py
index e166577b..06c6f70b 100644
--- a/src/bitmessageqt/__init__.py
+++ b/src/bitmessageqt/__init__.py
@@ -659,6 +659,9 @@ class MyForm(settingsmixin.SMainWindow):
         # Initialize addressbook
         QtCore.QObject.connect(self.ui.tableWidgetAddressBook, QtCore.SIGNAL(
             "itemChanged(QTableWidgetItem *)"), self.tableWidgetAddressBookItemChanged)
+        # This is necessary for the completer to work if multiple recipients
+        QtCore.QObject.connect(self.ui.lineEditTo, QtCore.SIGNAL(
+            "cursorPositionChanged(int, int)"), self.ui.lineEditTo.completer().onCursorPositionChanged)
 
         # show messages from message list
         QtCore.QObject.connect(self.ui.tableWidgetInbox, QtCore.SIGNAL(
@@ -1889,18 +1892,21 @@ class MyForm(settingsmixin.SMainWindow):
             label, address = row
             newRows[address] = [label, AccountMixin.NORMAL]
 
+        completerList = []
         for address in sorted(oldRows, key = lambda x: oldRows[x][2], reverse = True):
             if address in newRows:
+                completerList.append(newRows[address][0] + " <" + address + ">")
                 newRows.pop(address)
             else:
                 self.ui.tableWidgetAddressBook.removeRow(oldRows[address][2])
         for address in newRows:
             addRow(address, newRows[address][0], newRows[address][1])
+            completerList.append(newRows[address][0] + " <" + address + ">")
 
         # sort
         self.ui.tableWidgetAddressBook.sortByColumn(0, Qt.AscendingOrder)
         self.ui.tableWidgetAddressBook.setSortingEnabled(True)
-
+        self.ui.lineEditTo.completer().model().setStringList(completerList)
 
     def rerenderSubscriptions(self):
         self.rerenderTabTreeSubscriptions()
@@ -1956,7 +1962,11 @@ class MyForm(settingsmixin.SMainWindow):
                 toAddressesList))  # remove duplicate addresses. If the user has one address with a BM- and the same address without the BM-, this will not catch it. They'll send the message to the person twice.
             for toAddress in toAddressesList:
                 if toAddress != '':
-                    if toAddress.find("@") >= 0:
+                    # label plus address
+                    if "<" in toAddress and ">" in toAddress:
+                        toAddress = toAddress.split('<')[1].split('>')[0]
+                    # email address
+                    elif toAddress.find("@") >= 0:
                         if isinstance(acct, GatewayAccount):
                             acct.createMessage(toAddress, fromAddress, subject, message)
                             subject = acct.subject
diff --git a/src/bitmessageqt/bitmessageui.py b/src/bitmessageqt/bitmessageui.py
index 1a0e87ec..1761dfe3 100644
--- a/src/bitmessageqt/bitmessageui.py
+++ b/src/bitmessageqt/bitmessageui.py
@@ -8,6 +8,7 @@
 # WARNING! All changes made in this file will be lost!
 
 from PyQt4 import QtCore, QtGui
+from foldertree import AddressBookCompleter
 from messageview import MessageView
 from messagecompose import MessageCompose
 import settingsmixin
@@ -185,6 +186,11 @@ class Ui_MainWindow(object):
         self.tableWidgetAddressBook.horizontalHeader().setStretchLastSection(True)
         self.tableWidgetAddressBook.verticalHeader().setVisible(False)
         self.verticalSplitter_2.addWidget(self.tableWidgetAddressBook)
+        self.addressBookCompleter = AddressBookCompleter()
+        self.addressBookCompleter.setCompletionMode(QtGui.QCompleter.PopupCompletion)
+        self.addressBookCompleter.setCaseSensitivity(QtCore.Qt.CaseInsensitive)
+        self.addressBookCompleterModel = QtGui.QStringListModel()
+        self.addressBookCompleter.setModel(self.addressBookCompleterModel)
         self.pushButtonAddAddressBook = QtGui.QPushButton(self.send)
         self.pushButtonAddAddressBook.setObjectName(_fromUtf8("pushButtonAddAddressBook"))
         self.pushButtonAddAddressBook.resize(200, self.pushButtonAddAddressBook.height())
@@ -239,6 +245,7 @@ class Ui_MainWindow(object):
         self.lineEditTo = QtGui.QLineEdit(self.sendDirect)
         self.lineEditTo.setObjectName(_fromUtf8("lineEditTo"))
         self.gridLayout_2.addWidget(self.lineEditTo, 1, 1, 1, 1)
+        self.lineEditTo.setCompleter(self.addressBookCompleter)
         self.gridLayout_2_Widget = QtGui.QWidget()
         self.gridLayout_2_Widget.setLayout(self.gridLayout_2)
         self.verticalSplitter_5.addWidget(self.gridLayout_2_Widget)
diff --git a/src/bitmessageqt/foldertree.py b/src/bitmessageqt/foldertree.py
index d3c7817f..e77ea74b 100644
--- a/src/bitmessageqt/foldertree.py
+++ b/src/bitmessageqt/foldertree.py
@@ -1,4 +1,5 @@
 from PyQt4 import QtCore, QtGui
+from string import find, rfind, rstrip, lstrip
 
 from helper_sql import *
 from utils import *
@@ -478,3 +479,56 @@ class Ui_AddressBookWidgetItemAddress(Ui_AddressBookWidgetItem):
         Ui_AddressBookWidgetItem.__init__(self, address, type)
         self.address = address
         self.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
+        
+class AddressBookCompleter(QtGui.QCompleter):
+    def __init__(self):
+        super(QtGui.QCompleter, self).__init__()
+        self.cursorPos = -1
+    
+    def onCursorPositionChanged(self, oldPos, newPos):
+        if oldPos != self.cursorPos:
+            self.cursorPos = -1
+        
+    def splitPath(self, path):
+        stringList = []
+        text = unicode(path.toUtf8())
+        splitIndex = rfind(text[0:self.widget().cursorPosition()], ";") + 1
+        str = text[splitIndex:self.widget().cursorPosition()]
+        str = rstrip(lstrip(str))
+        stringList.append(str)
+        return stringList
+        
+    def pathFromIndex(self, index):
+        autoString = unicode(index.data(QtCore.Qt.EditRole).toString())
+        text = unicode(self.widget().text().toUtf8())
+        
+        # If cursor position was saved, restore it, else save it
+        if self.cursorPos != -1:
+            self.widget().setCursorPosition(self.cursorPos)
+        else:
+            self.cursorPos = self.widget().cursorPosition()
+
+        # Get current prosition
+        curIndex = self.widget().cursorPosition()
+        
+        # prev_delimiter_index should actually point at final white space AFTER the delimiter
+        # Get index of last delimiter before current position
+        prevDelimiterIndex = rfind(text[0:curIndex], ";")
+        while text[prevDelimiterIndex + 1] == " ":
+            prevDelimiterIndex += 1
+            
+        # Get index of first delimiter after current position (or EOL if no delimiter after cursor)
+        nextDelimiterIndex = find(text, ";", curIndex)
+        if nextDelimiterIndex == -1:
+            nextDelimiterIndex = len(text)
+
+        # Get part of string that occurs before cursor
+        part1 = text[0:prevDelimiterIndex + 1]
+
+        # Get string value from before auto finished string is selected
+        pre = text[prevDelimiterIndex + 1:curIndex - 1];
+
+        # Get part of string that occurs AFTER cursor
+        part2 = text[nextDelimiterIndex:]
+
+        return part1 + autoString + part2;