Spoonerise words... in Finnish
JavaScript (ES6), 196 175 bytes
Takes the words as two strings in currying syntax (a)(b). Returns an array of two arrays of characters.
a=&gt;b=&gt;[(e=/(.*?)([eiäaöoyu])(\2?)(.*)/,g=(a,[,c,v])=&gt;[...c+v+(a[3]&amp;&amp;v)+a[4]].map(c=&gt;(j=e.search(v),i=e.search(c))&gt;9&amp;j&gt;9?e[i&amp;~1|j&amp;1]:c))(a=e.exec(a),b=e.exec(b),e+=e),g(b,a)]

Try it online!
How?
Each input word is passed through the regular expression e, which has 4 capturing groups:
e = /(.*?)([eiäaöoyu])(\2?)(.*)/    1: leading consonants (or empty)
     [ 1 ][     2    ][ 3 ][ 4]     2: first vowel
                                    3: doubled first vowel (or empty)
                                    4: all remaining characters

The helper function g() takes all capturing groups of the word to be updated as a[ ] and the first and second capturing groups of the other word as c and v.
We apply basic spoonerism and take care of long vowels with:
c + v + (a[3] &amp;&amp; v) + a[4]

To apply vowel harmony, we first coerce the regular expression e to a string by adding it to itself, which gives:
e = &quot;/(.*?)([eiäaöoyu])(\2?)(.*)//(.*?)([eiäaöoyu])(\2?)(.*)/&quot;
     ^^^^^^^^^^^^^^^^
     0123456789ABCDEF (position as hexa)

Vowels that need to be harmonized have a position greater than 9 in the resulting string. Furthermore, the expression was arranged in such a way that front vowels äöy are located at even positions, while back vowels aou are located at odd positions, next to their counterparts.
Hence the following translation formula which is applied to each character c of the output word:
(j = e.search(v), i = e.search(c)) &gt; 9 &amp; j &gt; 9 ? e[i &amp; ~1 | j &amp; 1] : c