diff --git a/markdownify/__init__.py b/markdownify/__init__.py
index 28cdaf6..94e18d7 100644
--- a/markdownify/__init__.py
+++ b/markdownify/__init__.py
@@ -41,6 +41,11 @@
# confused with a list item
re_escape_misc_list_items = re.compile(r'((?:\s|^)[0-9]{1,9})([.)](?:\s|$))')
+# Escape '|' characters in table cells, where they would otherwise be
+# parsed as column delimiters (even inside code spans). The negative
+# lookbehind skips pipes that escape_misc has already escaped.
+re_table_cell_pipe = re.compile(r'(?
| A | B |
|---|
| 1|2 | 3 |
') == '\n\n| A | B |\n| --- | --- |\n| 1\\|2 | 3 |\n\n'
+ assert md('') == '\n\n| A\\|B | C |\n| --- | --- |\n| 1 | 2 |\n\n'
+ assert md('') == '\n\n| A |\n| --- |\n| 1\\|2\\|3 |\n\n'
+ assert md('') == '\n\n| A |\n| --- |\n| \\| |\n\n'
+ assert md('') == '\n\n| A |\n| --- |\n| **1\\|2** |\n\n'
+ assert md('') == '\n\n| A |\n| --- |\n| [1\\|2](#) |\n\n'
+ # GFM tables require pipes to be escaped even inside code spans
+ assert md('') == '\n\n| A |\n| --- |\n| `1\\|2` |\n\n'
+ assert md('') == '\n\n| A | B |\n| --- | --- |\n| 1\\|2 | |\n\n'
+ # escape_misc=True escapes pipes on its own; make sure they are not escaped twice
+ assert md('', escape_misc=True) == '\n\n| A |\n| --- |\n| 1\\|2 |\n\n'
+ # pipes outside of tables are unaffected
+ assert md('1|2') == '1|2'
+
+ # every row keeps the delimiter count of a two-column table
+ result = md('')
+ assert [len(re.findall(r'(?