diff --git a/src/canvas.js b/src/canvas.js
index aef6f638e..c79e3e6ae 100644
--- a/src/canvas.js
+++ b/src/canvas.js
@@ -561,6 +561,22 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
             this.current.fillAlpha = state[1];
             this.ctx.globalAlpha = state[1];
             break;
+          case 'BM':
+            if (value && value.name && (value.name !== 'Normal')) {
+              var mode = value.name.replace(/([A-Z])/g,
+                function(c) {
+                  return '-' + c.toLowerCase();
+                }
+              ).substring(1);
+              this.ctx.globalCompositeOperation = mode;
+              if (this.ctx.globalCompositeOperation !== mode) {
+                warn('globalCompositeOperation "' + mode +
+                     '" is not supported');
+              }
+            } else {
+              this.ctx.globalCompositeOperation = 'source-over';
+            }
+            break;
         }
       }
     },
diff --git a/src/evaluator.js b/src/evaluator.js
index ec076a273..5c52ba848 100644
--- a/src/evaluator.js
+++ b/src/evaluator.js
@@ -497,6 +497,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
                     case 'FL':
                     case 'CA':
                     case 'ca':
+                    case 'BM':
                       gsStateObj.push([key, value]);
                       break;
                     case 'Font':
@@ -506,11 +507,6 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
                         value[1]
                       ]);
                       break;
-                    case 'BM':
-                      // We support the default so don't trigger the TODO.
-                      if (!isName(value) || value.name != 'Normal')
-                        TODO('graphic state operator ' + key);
-                      break;
                     case 'SMask':
                       // We support the default so don't trigger the TODO.
                       if (!isName(value) || value.name != 'None')
diff --git a/test/pdfs/blendmode.pdf b/test/pdfs/blendmode.pdf
new file mode 100644
index 000000000..9cba305b5
Binary files /dev/null and b/test/pdfs/blendmode.pdf differ
diff --git a/test/test_manifest.json b/test/test_manifest.json
index acc4b4157..a9d876e09 100644
--- a/test/test_manifest.json
+++ b/test/test_manifest.json
@@ -838,6 +838,13 @@
       "rounds": 1,
       "type": "eq"
     },
+    {  "id": "blendmode",
+      "file": "pdfs/blendmode.pdf",
+      "md5": "374800cf78ce4b4abd02cd10a856b57f",
+      "rounds": 1,
+      "type": "eq",
+      "about": "Every blend mode that PDF supports."
+    },
     {  "id": "issue2462",
       "file": "pdfs/issue2462.pdf",
       "md5": "d4e3dddfdd35464c71cf0310bff29b42",