diff --git a/memcache.inc b/memcache.inc
index 4dc5b07..b28e402 100644
--- a/memcache.inc
+++ b/memcache.inc
@@ -76,6 +76,12 @@ class MemCacheDrupal implements DrupalCacheInterface {
         // Cache item expired, return FALSE.
         $cache = FALSE;
       }
+      // Temporary items created before the cache was last flushed by
+      // cache_clear_all(NULL, $bin) are invalid.
+      elseif (!empty($cache->temporary) && $cache->created + $this->cache_lifetime <= $this->cache_temporary_flush) {
+        // CACHE_TEMPORARY item expired, return FALSE.
+        $cache = FALSE;
+      }
       // Finally, check for wildcard clears against this cid.
       else {
         if (!$this->wildcard_valid($cid, $cache)) {
@@ -126,15 +132,19 @@ class MemCacheDrupal implements DrupalCacheInterface {
       // Convert CACHE_TEMPORARY (-1) into something that will live in memcache
       // until the next flush.
       $cache->expire = REQUEST_TIME + 2591999;
+      // This is a temporary cache item.
+      $cache->temporary = TRUE;
     }
     // Expire time is in seconds if less than 30 days, otherwise is a timestamp.
     else if ($expire != CACHE_PERMANENT && $expire < 2592000) {
       // Expire is expressed in seconds, convert to the proper future timestamp
       // as expected in dmemcache_get().
       $cache->expire = REQUEST_TIME + $expire;
+      $cache->temporary = FALSE;
     }
     else {
       $cache->expire = $expire;
+      $cache->temporary = FALSE;
     }
 
     // Manually track the expire time in $cache->expire.  When the object
@@ -185,10 +195,16 @@ class MemCacheDrupal implements DrupalCacheInterface {
     }
     if (empty($cid) || $wildcard === TRUE) {
       // system_cron() flushes all cache bins returned by hook_flush_caches()
-      // with cache_clear_all(NULL, $bin); This is for garbage collection with
-      // the database cache, but serves no purpose with memcache. So return
-      // early here.
+      // with cache_clear_all(NULL, $bin); The expected behaviour in this case
+      // is to perform garbage collection on expired cache items (which is
+      // irrelevant to memcache) but also to remove all CACHE_TEMPORARY items.
+      // @see https://api.drupal.org/api/drupal/includes!cache.inc/function/cache_clear_all/7
       if (!isset($cid)) {
+        // Update the timestamp of the last CACHE_TEMPORARY clear. All
+        // temporary cache items created before this will be invalidated.
+        $this->cache_temporary_flush = time();
+        $this->variable_set("cache_temporary_flush_$this->bin", $this->cache_temporary_flush);
+        // Return early here as we do not want to register a wildcard flush.
         return;
       }
       elseif ($cid == '*') {
@@ -382,6 +398,7 @@ class MemCacheDrupal implements DrupalCacheInterface {
     $this->cache_lifetime = variable_get('cache_lifetime', 0);
     $this->cache_flush = variable_get('cache_flush_' . $this->bin);
     $this->cache_content_flush = variable_get('cache_content_flush_' . $this->bin, 0);
+    $this->cache_temporary_flush = variable_get('cache_temporary_flush_' . $this->bin, 0);
     $this->flushed = min($this->cache_flush, REQUEST_TIME - $this->cache_lifetime);
   }
 
diff --git a/tests/memcache.test b/tests/memcache.test
index 73c01d3..d1b3c20 100644
--- a/tests/memcache.test
+++ b/tests/memcache.test
@@ -393,6 +393,30 @@ class MemCacheClearCase extends MemcacheTestCase {
     $this->assertCacheRemoved(t('Foofoo cache invalidated.'), 'foofoo');
   }
 
+  /**
+   * Test CACHE_TEMPORARY and CACHE_PERMANENT behaviour.
+   */
+  function testClearTemporaryPermanent() {
+    cache_set('test_cid_clear_temporary', $this->default_value, $this->default_bin, CACHE_TEMPORARY);
+    cache_set('test_cid_clear_permanent', $this->default_value, $this->default_bin, CACHE_PERMANENT);
+    cache_set('test_cid_clear_future', $this->default_value, $this->default_bin, time() + 3600);
+
+    $this->assertTrue($this->checkCacheExists('test_cid_clear_temporary', $this->default_value)
+                      && $this->checkCacheExists('test_cid_clear_permanent', $this->default_value)
+                      && $this->checkCacheExists('test_cid_clear_future', $this->default_value),
+                      t('Three cache items were created for checking cache expiry.'));
+
+    // This should clear only expirable items (CACHE_TEMPORARY).
+    cache_clear_all(NULL, $this->default_bin, TRUE);
+
+    $this->assertFalse($this->checkCacheExists('test_cid_clear_temporary', $this->default_value),
+                      t('Temporary cache item was removed after clearing cid NULL.'));
+    $this->assertTrue($this->checkCacheExists('test_cid_clear_permanent', $this->default_value),
+                      t('Permanent cache item was not removed after clearing cid NULL.'));
+    $this->assertTrue($this->checkCacheExists('test_cid_clear_future', $this->default_value),
+                      t('Future cache item was not removed after clearing cid NULL.'));
+  }
+
 
   /**
    * Test clearing using a cid.
