diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/plug/ProtonSessionIntegrationCallback.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/plug/ProtonSessionIntegrationCallback.java
index c3ac671..506d6ea 100644
--- a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/plug/ProtonSessionIntegrationCallback.java
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/plug/ProtonSessionIntegrationCallback.java
@@ -45,6 +45,7 @@
 import org.apache.activemq.artemis.utils.SimpleIDGenerator;
 import org.apache.activemq.artemis.utils.UUIDGenerator;
 import org.apache.qpid.proton.amqp.Binary;
+import org.apache.qpid.proton.amqp.Symbol;
 import org.apache.qpid.proton.amqp.messaging.Accepted;
 import org.apache.qpid.proton.amqp.messaging.Rejected;
 import org.apache.qpid.proton.amqp.transport.AmqpError;
@@ -59,6 +60,7 @@
 import org.proton.plug.SASLResult;
 import org.proton.plug.context.ProtonPlugSender;
 import org.proton.plug.exceptions.ActiveMQAMQPResourceLimitExceededException;
+import org.proton.plug.logger.ActiveMQAMQPProtocolMessageBundle;
 import org.proton.plug.sasl.PlainSASLResult;
 
 public class ProtonSessionIntegrationCallback implements AMQPSessionCallback, SessionCallback {
@@ -372,6 +374,21 @@
       if (address != null) {
          message.setAddress(new SimpleString(address));
       }
+      else {
+         // Anonymous relay must set a To value
+         if (message.getAddress() == null) {
+            // TODO - Suppose this can just be a throw, looks like the caller will reject.
+            rejectMessage(delivery, Symbol.valueOf("failed"), "Missing to field for message sent to an anonymous producer");
+            return;
+         }
+
+         // TODO - This probably can be optimized to not do this every time via a cache or some such
+         if (!bindingQuery(address)) {
+            throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.addressDoesntExist();
+         }
+
+         // TODO - Security check ?
+      }
 
       recoverContext();
 
@@ -386,7 +403,7 @@
             }
          }
          else {
-            rejectMessage(delivery);
+            rejectMessage(delivery, AmqpError.RESOURCE_LIMIT_EXCEEDED, "Address is full: " + address);
          }
       }
       else {
@@ -394,11 +411,12 @@
       }
    }
 
-   private void rejectMessage(Delivery delivery) {
-      String address = delivery.getLink().getTarget().getAddress();
-      ErrorCondition ec = new ErrorCondition(AmqpError.RESOURCE_LIMIT_EXCEEDED, "Address is full: " + address);
+   private void rejectMessage(Delivery delivery, Symbol errorCondition, String errorMessage) {
+      ErrorCondition condition = new ErrorCondition();
+      condition.setCondition(errorCondition);
+      condition.setDescription(errorMessage);
       Rejected rejected = new Rejected();
-      rejected.setError(ec);
+      rejected.setError(condition);
       delivery.disposition(rejected);
       connection.flush();
    }
@@ -441,6 +459,13 @@
 
    @Override
    public void offerProducerCredit(final String address, final int credits, final int threshold, final Receiver receiver) {
+      // TODO - Do something smart here with the paging bits to figure out the credit can be sent.
+      if (address == null) {
+         receiver.flow(credits);
+         connection.flush();
+         return;
+      }
+
       try {
          final PagingStore store = manager.getServer().getPagingManager().getPageStore(new SimpleString(address));
          store.checkMemory(new Runnable() {
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/server/ProtonServerConnectionContext.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/server/ProtonServerConnectionContext.java
index 4124c2f..16805bb 100644
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/server/ProtonServerConnectionContext.java
+++ b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/server/ProtonServerConnectionContext.java
@@ -17,6 +17,7 @@
 package org.proton.plug.context.server;
 
 import static org.proton.plug.AmqpSupport.DELAYED_DELIVERY;
+import static org.proton.plug.AmqpSupport.ANONYMOUS_RELAY;
 
 import org.apache.qpid.proton.amqp.Symbol;
 import org.apache.qpid.proton.amqp.transaction.Coordinator;
@@ -83,6 +84,6 @@
    }
 
    public Symbol[] getConnectionCapabilitiesOffered() {
-      return new Symbol[]{DELAYED_DELIVERY};
+      return new Symbol[]{ANONYMOUS_RELAY, DELAYED_DELIVERY};
    }
 }
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/server/ProtonServerReceiverContext.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/server/ProtonServerReceiverContext.java
index c564a9e..2f408c5 100644
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/server/ProtonServerReceiverContext.java
+++ b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/server/ProtonServerReceiverContext.java
@@ -67,7 +67,7 @@
 
       if (target != null) {
          if (target.getDynamic()) {
-            //if dynamic we have to create the node (queue) and set the address on the target, the node is temporary and
+            // if dynamic we have to create the node (queue) and set the address on the target, the node is temporary and
             // will be deleted on closing of the session
             address = sessionSPI.tempQueueName();
 
@@ -80,23 +80,22 @@
             target.setAddress(address);
          }
          else {
-            //if not dynamic then we use the targets address as the address to forward the messages to, however there has to
-            //be a queue bound to it so we nee to check this.
+            // the target will have an address unless the remote is requesting an anonymous
+            // relay in which case the address in the incoming message's to field will be
+            // matched on receive of the message.
             address = target.getAddress();
-            if (address == null) {
-               throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.targetAddressNotSet();
-            }
-
-            try {
-               if (!sessionSPI.bindingQuery(address)) {
-                  throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.addressDoesntExist();
+            if (address != null && !address.isEmpty()) {
+               try {
+                  if (!sessionSPI.bindingQuery(address)) {
+                     throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.addressDoesntExist();
+                  }
                }
-            }
-            catch (ActiveMQAMQPNotFoundException e) {
-               throw e;
-            }
-            catch (Exception e) {
-               throw new ActiveMQAMQPInternalErrorException(e.getMessage(), e);
+               catch (ActiveMQAMQPNotFoundException e) {
+                  throw e;
+               }
+               catch (Exception e) {
+                  throw new ActiveMQAMQPInternalErrorException(e.getMessage(), e);
+               }
             }
          }
       }
diff --git a/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/AmqpMessage.java b/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/AmqpMessage.java
index 320d174..35a1eb2 100644
--- a/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/AmqpMessage.java
+++ b/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/AmqpMessage.java
@@ -166,6 +166,31 @@
    //----- Convenience methods for constructing outbound messages -----------//
 
    /**
+    * Sets the address which is applied to the AMQP message To field in the message properties
+    *
+    * @param address
+    *      The address that should be applied in the Message To field.
+    */
+   public void setAddress(String address) {
+      checkReadOnly();
+      lazyCreateProperties();
+      getWrappedMessage().setAddress(address);
+   }
+
+   /**
+    * Return the set address that was set in the Message To field.
+    *
+    * @return the set address String form or null if not set.
+    */
+   public String getAddress() {
+      if (message.getProperties() == null) {
+         return null;
+      }
+
+      return message.getProperties().getTo();
+   }
+
+   /**
     * Sets the MessageId property on an outbound message using the provided String
     *
     * @param messageId the String message ID value to set.
diff --git a/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/AmqpSession.java b/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/AmqpSession.java
index 82b6aec..324b885 100644
--- a/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/AmqpSession.java
+++ b/tests/artemis-test-support/src/main/java/org/apache/activemq/transport/amqp/client/AmqpSession.java
@@ -52,6 +52,16 @@
    }
 
    /**
+    * Create an anonymous sender instance using the anonymous relay support of the broker.
+    *
+    * @return a newly created sender that is ready for use.
+    * @throws Exception if an error occurs while creating the sender.
+    */
+   public AmqpSender createAnonymousSender() throws Exception {
+      return createSender(null, false);
+   }
+
+   /**
     * Create a sender instance using the given address
     *
     * @param address the address to which the sender will produce its messages.
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/proton/ProtonTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/proton/ProtonTest.java
index 8da5aa2..a247e45 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/proton/ProtonTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/proton/ProtonTest.java
@@ -18,6 +18,7 @@
 
 import static org.proton.plug.AmqpSupport.contains;
 import static org.proton.plug.AmqpSupport.DELAYED_DELIVERY;
+import static org.proton.plug.AmqpSupport.ANONYMOUS_RELAY;
 import static org.proton.plug.AmqpSupport.PRODUCT;
 import static org.proton.plug.AmqpSupport.VERSION;
 
@@ -229,6 +230,11 @@
          public void inspectOpenedResource(org.apache.qpid.proton.engine.Connection connection) {
 
             Symbol[] offered = connection.getRemoteOfferedCapabilities();
+
+            if (!contains(offered, ANONYMOUS_RELAY)) {
+               markAsInvalid("Broker did not indicate it support anonymous relay links");
+               return;
+            }
 
             if (!contains(offered, DELAYED_DELIVERY)) {
                markAsInvalid("Broker did not indicate it support delayed message delivery");
@@ -471,6 +477,115 @@
       assertTrue(addressSize >= maxSizeBytesRejectThreshold);
    }
 
+   @Test(timeout = 60000)
+   public void testSendMessageOnAnonymousRelayLinkUsingMessageTo() throws Exception {
+      if (protocol != 0 && protocol != 3) return; // Only run this test for AMQP protocol
+
+      AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password);
+      AmqpConnection connection = client.connect();
+      AmqpSession session = connection.createSession();
+
+      AmqpSender sender = session.createAnonymousSender();
+      AmqpMessage message = new AmqpMessage();
+
+      message.setAddress(address);
+      message.setMessageId("msg" + 1);
+      message.setText("Test-Message");
+
+      sender.send(message);
+      sender.close();
+
+      AmqpReceiver receiver = session.createReceiver(address);
+      receiver.flow(1);
+      AmqpMessage received = receiver.receive(10, TimeUnit.SECONDS);
+      assertNotNull("Should have read message", received);
+      assertEquals("msg1", received.getMessageId());
+      received.accept();
+
+      receiver.close();
+
+      connection.close();
+   }
+
+   @Test(timeout = 60000)
+   public void testSendMessageFailsOnAnonymousRelayLinkWhenNoToValueSet() throws Exception {
+      if (protocol != 0 && protocol != 3) return; // Only run this test for AMQP protocol
+
+      AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password);
+      AmqpConnection connection = client.connect();
+      AmqpSession session = connection.createSession();
+
+      AmqpSender sender = session.createAnonymousSender();
+      AmqpMessage message = new AmqpMessage();
+
+      message.setMessageId("msg" + 1);
+      message.setText("Test-Message");
+
+      try {
+         sender.send(message);
+         fail("Should not be able to send, message should be rejected");
+      }
+      catch (Exception ex) {
+      }
+
+      sender.close();
+      connection.close();
+   }
+
+   @Test(timeout = 60000)
+   public void testSendMessageFailsOnAnonymousRelayWhenToFieldHasNonExistingAddress() throws Exception {
+      if (protocol != 0 && protocol != 3) return; // Only run this test for AMQP protocol
+
+      AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password);
+      AmqpConnection connection = client.connect();
+      AmqpSession session = connection.createSession();
+
+      AmqpSender sender = session.createAnonymousSender();
+      AmqpMessage message = new AmqpMessage();
+
+      message.setAddress(address + "-not-in-service");
+      message.setMessageId("msg" + 1);
+      message.setText("Test-Message");
+
+      try {
+         sender.send(message);
+         fail("Should not be able to send, message should be rejected");
+      }
+      catch (Exception ex) {
+      }
+
+      sender.close();
+      connection.close();
+   }
+
+   @Test(timeout = 60000)
+   public void testSendMessageFailsOnAnonymousRelayWhenNotAuthorizedToSendToAddress() throws Exception {
+      if (protocol != 0 && protocol != 3) return; // Only run this test for AMQP protocol
+
+      AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password);
+      AmqpConnection connection = client.connect();
+      AmqpSession session = connection.createSession();
+
+      AmqpSender sender = session.createAnonymousSender();
+      AmqpMessage message = new AmqpMessage();
+
+      message.setAddress(address + "-somthing-not-authorized");
+      message.setMessageId("msg" + 1);
+      message.setText("Test-Message");
+
+      // TODO - Need to configure send to address that is not authorized for this user
+      try {
+         sender.send(message);
+         fail("Should not be able to send, message should be rejected");
+      }
+      catch (Exception ex) {
+         fail("Not yet implemented");  // TODO - REMOVE ME ONCE THIS IS IMPLEMENTED
+      }
+
+      sender.close();
+      connection.close();
+   }
+
    @Test
    public void testAddressIsBlockedForOtherProdudersWhenFull() throws Exception {
       if (protocol != 0 && protocol != 3) return; // Only run this test for AMQP protocol
