diff --git a/plugins/calendar/calendar.php b/plugins/calendar/calendar.php
--- a/plugins/calendar/calendar.php
+++ b/plugins/calendar/calendar.php
@@ -1239,23 +1239,31 @@
                 $noreply = intval($noreply) || $status == 'needs-action' || $itip_sending === 0;
                 $reload  = $event['calendar'] != $ev['calendar'] || !empty($event['recurrence']) ? 2 : 1;
                 $emails  = $this->get_user_emails();
+                $ownedResourceEmails  = $this->owned_resources_emails($emails);
                 $organizer = null;
+                $resourceConfirmation = false;
 
                 foreach ($event['attendees'] as $i => $attendee) {
                     if ($attendee['role'] == 'ORGANIZER') {
                         $organizer = $attendee;
                     }
-                    else if (!empty($attendee['email']) && in_array(strtolower($attendee['email']), $emails)) {
+                    else if (!empty($attendee['email']) && in_array_nocase($attendee['email'], $emails)) {
                         $reply_sender = $attendee['email'];
                     }
+                    else if (!empty($attendee['cutype']) && $attendee['cutype'] == 'RESOURCE' && !empty($attendee['email']) && in_array_nocase($attendee['email'], $ownedResourceEmails)) {
+                        $resourceConfirmation = true;
+                        // Note on behalf of which resource this update is going to be sent out
+                        $event['_resource'] = $attendee['email'];
+                    }
                 }
 
                 if (!$noreply) {
                     $itip = $this->load_itip();
                     $itip->set_sender_email($reply_sender);
                     $event['thisandfuture'] = $event['_savemode'] == 'future';
+                    $bodytextprefix = $resourceConfirmation ? 'itipmailbodyresource' : 'itipmailbody';
 
-                    if ($organizer && $itip->send_itip_message($event, 'REPLY', $organizer, 'itipsubject' . $status, 'itipmailbody' . $status)) {
+                    if ($organizer && $itip->send_itip_message($event, 'REPLY', $organizer, 'itipsubject' . $status, $bodytextprefix . $status)) {
                         $mailto = !empty($organizer['name']) ? $organizer['name'] : $organizer['email'];
                         $msg    = $this->gettext(['name' => 'sentresponseto', 'vars' => ['mailto' => $mailto]]);
 
@@ -2006,10 +2014,12 @@
             }
 
             $identity['emails'][] = $this->rc->user->get_username();
+            $identity['ownedResources'] = $this->owned_resources_emails($identity['emails']);
             $settings['identity'] = [
                 'name'   => $identity['name'],
                 'email'  => strtolower($identity['email']),
-                'emails' => ';' . strtolower(join(';', $identity['emails']))
+                'emails' => ';' . strtolower(join(';', $identity['emails'])),
+                'ownedResources' => ';' . strtolower(join(';', $identity['ownedResources']))
             ];
         }
 
@@ -2868,6 +2878,21 @@
         exit;
     }
 
+    /**
+     * List email addressed of owned resources
+     */
+    private function owned_resources_emails($identities)
+    {
+        $results = [];
+        if ($directory = $this->resources_directory()) {
+            foreach ($directory->load_owned_resources($identities) as $rec) {
+                $results[] = $rec['email'];
+            }
+        }
+        return $results;
+    }
+
+
     /****  Event invitation plugin hooks ****/
 
     /**
diff --git a/plugins/calendar/calendar_ui.js b/plugins/calendar/calendar_ui.js
--- a/plugins/calendar/calendar_ui.js
+++ b/plugins/calendar/calendar_ui.js
@@ -460,7 +460,7 @@
         for (var j=0; j < num_attendees; j++) {
           data = event.attendees[j];
           if (data.email) {
-            if (data.role != 'ORGANIZER' && settings.identity.emails.indexOf(';'+data.email) >= 0) {
+            if (data.role != 'ORGANIZER' && is_this_me(data.email)) {
               mystatus = (data.status || 'UNKNOWN').toLowerCase();
               if (data.status == 'NEEDS-ACTION' || data.status == 'TENTATIVE' || data.rsvp)
                 rsvp = mystatus;
@@ -2380,6 +2380,14 @@
         add_attendee($.extend({ role:'REQ-PARTICIPANT', status:'NEEDS-ACTION', cutype:'RESOURCE' }, resource));
     }
 
+    var is_this_me = function(email)
+    {
+      if (settings.identity.emails.indexOf(';'+email) >= 0 || settings.identity.ownedResources.indexOf(';'+email) >= 0) {
+        return true;
+      }
+      return false;
+    };
+
     // when the user accepts or declines an event invitation
     var event_rsvp = function(response, delegate, replymode, event)
     {
@@ -2414,7 +2422,8 @@
         attendees = [];
         for (var data, i=0; i < me.selected_event.attendees.length; i++) {
           data = me.selected_event.attendees[i];
-          if (settings.identity.emails.indexOf(';'+String(data.email).toLowerCase()) >= 0) {
+          //FIXME this can only work if there is a single resource per invitation
+          if (is_this_me(String(data.email).toLowerCase())) {
             data.status = response.toUpperCase();
             data.rsvp = 0;  // unset RSVP flag
 
diff --git a/plugins/calendar/drivers/ldap/resources_driver_ldap.php b/plugins/calendar/drivers/ldap/resources_driver_ldap.php
--- a/plugins/calendar/drivers/ldap/resources_driver_ldap.php
+++ b/plugins/calendar/drivers/ldap/resources_driver_ldap.php
@@ -71,6 +71,41 @@
         return $results;
     }
 
+    /**
+     * Fetch resource objects filtered by owner email addresses
+     *
+     * @param array $emails List of email addresses of the owner
+     * @param int   $num    Max size of the result
+     *
+     * @return array List of resource records
+     */
+    public function load_owned_resources($emails, $num = 5000)
+    {
+        if (!($ldap = $this->connect())) {
+            return [];
+        }
+
+        $ldap->set_pagesize($num);
+
+        $ownerDns = [];
+        $results = $ldap->search('email', $emails, 0, true, true);
+        if ($results instanceof ArrayAccess) {
+            foreach ($results as $i => $rec) {
+                $ownerDns[] = $rec['dn'];
+            }
+        }
+
+        $results = $ldap->search('owner', $ownerDns, 0, true, true);
+
+        if ($results instanceof ArrayAccess) {
+            foreach ($results as $i => $rec) {
+                $results[$i] = $this->decode_resource($rec);
+            }
+        }
+
+        return $results;
+    }
+
     /**
      * Return properties of a single resource
      *
diff --git a/plugins/calendar/drivers/resources_driver.php b/plugins/calendar/drivers/resources_driver.php
--- a/plugins/calendar/drivers/resources_driver.php
+++ b/plugins/calendar/drivers/resources_driver.php
@@ -45,6 +45,19 @@
      */
     abstract public function load_resources($query = null);
 
+    /**
+     * Fetch resource objects filtered by owner email addresses
+     *
+     * @param array $emails List of email addresses of the owner
+     * @param int   $num    Max size of the result
+     *
+     * @return array List of resource records
+     */
+    public function load_owned_resources($emails, $num = 5000)
+    {
+        return [];
+    }
+
     /**
      * Return properties of a single resource
      *
diff --git a/plugins/calendar/localization/en_US.inc b/plugins/calendar/localization/en_US.inc
--- a/plugins/calendar/localization/en_US.inc
+++ b/plugins/calendar/localization/en_US.inc
@@ -207,6 +207,10 @@
 $labels['itipmailbodydelegated'] = "\$sender has delegated the participation in the following event:\n\n*\$title*\n\nWhen: \$date";
 $labels['itipmailbodydelegatedto'] = "\$sender has delegated the participation in the following event to you:\n\n*\$title*\n\nWhen: \$date";
 
+$labels['itipmailbodyresourceaccepted'] = "\$sender has accepted the following resource booking:\n\n*\$title*\n\nWhen: \$date\n\nInvitees: \$attendees";
+$labels['itipmailbodyresourcetentative'] = "\$sender has tentatively accepted the following resource booking:\n\n*\$title*\n\nWhen: \$date\n\nInvitees: \$attendees";
+$labels['itipmailbodyresourcedeclined'] = "\$sender has declined the the following resource booking:\n\n*\$title*\n\nWhen: \$date\n\nInvitees: \$attendees";
+
 $labels['itipdeclineevent'] = 'Do you want to decline your invitation to this event?';
 $labels['declinedeleteconfirm'] = 'Do you also want to delete this declined event from your calendar?';
 $labels['itipcomment'] = 'Invitation/notification comment';
diff --git a/plugins/libcalendaring/lib/libcalendaring_itip.php b/plugins/libcalendaring/lib/libcalendaring_itip.php
--- a/plugins/libcalendaring/lib/libcalendaring_itip.php
+++ b/plugins/libcalendaring/lib/libcalendaring_itip.php
@@ -219,6 +219,11 @@
                 if ($attendee['role'] == 'ORGANIZER') {
                     $reply_attendees[] = $attendee;
                 }
+                // we accept on behalf of a resource
+                else if (strcasecmp($attendee['email'], $event['_resource']) == 0) {
+                    $replying_attendee = $attendee;
+                    $replying_attendee['sent-by'] = 'mailto:' . $from_utf;
+                }
                 else if (strcasecmp($attendee['email'], $from) == 0 || strcasecmp($attendee['email'], $from_utf) == 0) {
                     $replying_attendee = $attendee;
                     if ($attendee['status'] != 'DELEGATED') {